dvi2bitmap – convert DVI files to bitmap images

This application processes a DVI file produced by TeX, converting each page to a single bitmap. The conversion is done directly, rather than through a chain of intermediate file formats, making the process extremely fast. It can produce output as XBM, XPM, GIF and PNG files.

1 Introduction

dvi2bitmap converts the typeset output of TeX into a bitmap image.

The most common use-case is to convert TeX or LaTeX mathematics to HTML. It is possible to do this with a chain of general-purpose tools, for example going from DVI to postscript to PNM files to GIFs, but this is generally slow. For an overview of maths and SGML/HTML, see A Maths and SGML/HTML.

The tool dvi2bitmap does this processing in a single step, reading the DVI file and font files, and emitting a bitmap. It can, at present, generate XBM, XPM, GIF and, if the relevant library is installed, PNG files.

See 2 Usage for usage instructions, and for installation instructions.

The dvi2bitmap application is available for download at http://purl.org/nxg/dist/dvi2bitmap.

This document matches version 1.0 of the program (you can see what version you have with the command dvi2bitmap -V). This should currently be regarded as beta software.

2 Usage

Synopsis:

dvi2bitmap [flags] dvi-file

This program is intended to conform to the DVI processing standard.

The dvi-file argument is the name of a DVI file to be converted to a bitmap. dvi2bitmap looks for the file both with and without the default extension .dvi.

You may also read the DVI file from the standard input by giving the DVI file as "-", thus

cat myfile.dvi | dvi2bitmap -

is an alternative way of reading the file (rather pointless in this case, but it shows the principle; see 3.2 Using dvi2bitmap in a pipe for further discussion). For more arcane purposes, the DVI file may also be specified as <osfile>dvi-file (which is entirely equivalent), or <osfd>integer, where the given integer specifies an open file descriptor; specifying "-" as the input file is equivalent to <osfd>0

The motivation for this program was the need for a helper program to produce small bitmaps for inclusion in web pages. Accordingly, the program's underlying usage model is that one would generate a file of TeX or LaTeX material, convert it to a DVI file using TeX, and convert the result to a collection of bitmap files. The input text will typically be equations, but any other TeX material will work as well. For example, the processor which generates the HTML could spit out a file such as

\documentclass{article}
\pagestyle{empty}
\begin{document}
$E=mc^2$
\newpage
% etc...
\end{document}

and then this program can scoot through it turning each page into a bitmap. I had thought about some complicated scheme to delimit areas on the page, but realised that since the file being processed would typically be generated on the fly specifically for processing by a tool like this, this wasn't really necessary. See 6 Bugs, extras, and further developments for a script which can help with this.

I hope that the program is (or can be made to be) flexible enough to support other modes of use.

2.1 Options

Various of the options below have common syntax features.

[keyword-value-list]

This indicates a sequence of keyword=value pairs, separated by commas. Not all keywords necessarily have a value.

[boolean]

This can be `yes', `true' or `on' indicating true; or `no', `false' or `off' indicating false.

The options are as follows:

-c, --crop=[keyword-value-pairs]

The --crop option allows you to control how the generated bitmaps are cropped before they are written. The keywords are `left', `right', `top', `bottom' and `all', and the value in each case is the number of pixels to leave as a margin. If the keywords `relative' (default) or `absolute' are present, they refer to all of the keywords following: if the crop is specified as `relative', then the values specify the number of pixels to leave around the blackened pixels of the text; if the crop is `absolute', then it specifies the position of the crop (in pixels) from the left or top edge of the `page'. The specification ----crop=absolute,all=dimen, which would set all the crops to the same position, is silly, and so is forbidden.

The conversion from points to pixels takes account of the magnification set in the --magnification option, if that's been specified already, but it doesn't notice if that's set after this option, and it takes no account of any magnification in the DVI file.

See 2.2 DVI specials for TeX \special commands which set this within the TeX file.

See below for TeX \special commands which set this within the TeX file.

-F, --font-search=[keyword-value-list]

Specifies how dvi2bitmap is to find the fonts it needs. Keywords are as follows:

path[=list]: use the given list of filesystem paths to search for PK fonts, or enable using the default path, if =path is missing. The default path is given by the environment variable DVI2BITMAP_PK_PATH. See also the discussion of font searching below.

kpathsea: enable using the kpathsea library to find fonts. If the program was not built against the kpathsea library, this option has no effect.

command[=script]: enable using the given script to find fonts. If the argument is missing, this enables using the script configured into the program at compile-time. This script is any program which will search the filesystem and produce a single line on output, giving the full path to the specified font. For example, this might be given as kpsewhich pk %f.%dpk to run the kpsewhich program. The command name is a font-string template, as described 2.5.4 Font-string templates.

If the program does not find a font using whichever methods have been enabled then, following the pattern of dvips and other DVIware, it writes a file missfont.log in the current directory, containing commands which you can use to generate the fonts immediately or later.

none: disable all font-searching. The result is that only the missfont.log file is written.

Each of the keywords can be prefixed by `no' to turn off the corresponding option -- thus --font-search=nopath,nokpathsea,nocommand has the same effect as --font-search=none.

-G, --font-gen=[boolean], --font-gen=command[=script]

Switch automatic generation of fonts off and on. If --font-gen=command is given, then the command specified at compile time is used to generate fonts. If, further, a font-generation script is specified, then it will be used instead of the default. The specified script is a font-string template, as described below. The default for automatic font generation is set at compile time.

-g, --debug=[spec]

Switch on debugging. The [spec] is a list of letters indicating what to debug, as follows. You may trace bitmap generation (`b'), DVI file parsing (`d'), input (`i'), the main program (`m'), PK file searching and parsing (`p'), font rasterdata parsing (`r'), or various utility functions (`u', though this is actually only useful for the maintainer). If kpathsea is compiled in, then debugging PK files switches on kpathsea debugging also. Adding an extra `g' at the beginning of the spec increases still further the amount of debugging code. The debugging information may be uninformative or unintelligible; it might even crash the program (mention that to me).

-h, --height=size; -w, --width=size

Specify the height and width of the canvas on which the output bitmap is painted. The program tries to make an estimate of this based on information within the DVI file, but it can't efficiently get all the information it needs, so sometimes the estimate is wrong. If you get a warning message like Warning: p.12: bitmap too big: occupies (1183,1072)...(4134,6255). Requested 4100x6200 then you'll need to specify a bitmap size. The numbers (1183,1072)...(4134,6255) are the coordinates of the top-left and bottom-right of the bitmap: in this case --height=6300 --width=4200 would suffice. At some point, I'd like to make the bitmap `expandable', obviating the need for these options.

--help

Display outline help for the options on stderr, and exit

-l, --end-page

See option --start-page

-M, --font-mode=[mode]

Set the MetaFont mode which is used for generating font files. The default is ibmvga. If you set this, you will probably have to set the resolution to a consistent number.

-m, --magnification=[number]

The TeX magnification parameter which is used when processing the DVI file. It is a float, with 1.0 corresponding to no magnification (the default). This interacts with the resolution as follows: if you specify a resolution of 100, and a magnification of 2, then dvi2bitmap will search for PK files at 200 dpi.

-n, --nodvi

Do not actually process the DVI file, but read the DVI pre- and postamble. Useful in conjunction with the --query options. If this option is present, then the program returns non-zero if any fonts were missing (see also 2.3 Exit value). The -n is for brevity and consistency with other tools -- the behaviour can be alternatively specified as --process=nodvi

-o, --output=[filename-pattern]

Choose the output filename pattern. The value is a `printf' formatting string, with a single %d formatting descriptor, which will be replaced in output filenames with the page number. If there is no such descriptor, the filename `pattern' is used as-is for the first filename output, after which the program reverts to the default filename pattern. The filename pattern can be overridden on a per-page basis by a TeX \special embedded in the DVI file (see in 2.2 DVI specials). If there is no file extension, or if it does not match the output type, a suitable file extension will be added.

--pipe

Indicates that the dvi-file argument is a non-seekable file, such as a named or unnamed pipe. This is automatically the case if you specify the DVI file as stdin, "-".

-p, --start-page=num, -l, --end-page=num, -P, --page-range=[spec]

These select page ranges, using a slight extension of the notation used by dvips (and the same option letters, except that dvips uses -pp instead of -P).

The --start-page=snum and --end-page=enum options take single page numbers; if either of these is given, then the program will process pages from page snum to page enum, with the defaults being the corresponding extremes. The [spec] consists of a comma-separated sequence of page numbers and ranges (a-b); only those pages, and the pages falling in those ranges (inclusive of the end pages) are processed. Any of these specifications may be prefixed by either = or :n:. In the former case, DVI page numbers are used rather than the TeX \count register; in the latter case, the program examines the \count register rather than the default \count

You can specify both of these prefixes one or more times, but you cannot mix the --start-page and --end-page options with the --page-range option. The program will respect only the last --start-page and --end-page options, but the --page-range options are cumulative. There may be no spaces in the pagelist. The page numbers may be negative.

Examples:

dvi2bitmap --page-range=3,6-10 ...

process only the specified pages

dvi2bitmap --page-range=:2:1 ...

process only pages where \count2 was 1.

-Q, --query=[keyword-list]

Query various things. The available possibilities are as given below. The results of each of the queries is printed on a line by itself, prefixed by a `Q', the keyword and a space, so that, for example, each of the lines produced by the --query=missing-fonts option would start Qmissing-fonts cmbx10 110 ...

Some of these options (--query=missing-fonts and --query=missing-fontgen) are probably most useful with the -n or --process=options options, to investigate a DVI file before processing. Others (--query=types and --query=paper) are probably useful only with --process=options. The option --query=bitmaps is only useful if you do actually generate bitmaps. For consistency (and so you don't have to remember which ones do which), the appropriate --process option is not implied in any of them, and you have to give it explicitly.

--query=bitmaps

Prints on stdout a line for each bitmap it generates, giving the filename, horizontal size, and vertical size, in pixels. This also reports the position of any `mark' in the bitmap -- see .

-Qf, --query=missing-fonts

Show missing fonts. The program writes on standard output one line per missing font, starting with Qf or Qmissing-fonts (depending on which of the variants was given -- the shorter ones are less mnemonic, but more convenient to parse in scripts), then five fields: the font name, the DPI value it was looking for, the base-DPI of the font, the magnification factor, and a dummy metafont mode. This output might be massaged for use with the mktexpk (TeXLive) or MakeTeXPK (teTeX) scripts to generate the required fonts, but --query=missing-fontgen is more straightforward.

-QF, --query=all-fonts

As for --query=missing-fonts except that found fonts are also listed, all prefixed by Qall-fonts

-Qg, --query=missing-fontgen

As for --query=missing-fonts, except that the output consists of the string Qmissing-fontgen followed by a mktexpk or MakeTeXPK command which can be used to generate the font.

-QG, --query=all-fontgen

As for --query=missing-fonts, except that font-generation commands for found fonts are also listed, prefixed by Qall-fontgen.

Note: Only one of --query=missing-fonts, --query=all-fonts, --query=missing-fontgen and --query=all-fontgen should be specified -- if more than one appears, only the last one is respected -- if more than one appears, only the last one is respected. In each of these four cases, plus their short forms, font-generation is automatically suppressed. This is probably what you want (it's not obvious why you're querying this otherwise), but if you do not want this, then you can reenable font generation with --font-gen=true

--query=paper

Show the list of paper sizes which are predefined for the --paper-size option.

--query=types

List the output image formats which the program can generate, on stdout, separated by whitespace. The first output format is the default.

-r, --resolution=[number]

Specifies the output resolution, in pixels-per-inch. This is used when deciding which PK files to use. The default is 110, which matches the default ibmvga metafont mode.

-R, --colours=[keyword-value-list], --colors=[keyword-value-pairs]

Specifies the foreground or background colours, as RGB triples. The keywords are either foreground or background, and the values are a triple of integers separated by slashes, for example --colours=foreground=127/127/255. The integers must be in the range [0,255], and can be specified in decimal, octal or hex (for example 127=0177=0x7f), or else the whole spec may be of the form #rrggbb, where `rr', `gg' and `bb' are each a pair of hex digits.

-s, --scaledown=[number]

Reduces the linear size of the output bitmap by the given factor (default 1).

-T, --output=type=[type]

Choose the output format, which can be png, gif, xpm or xbm. The program generates XBM bitmaps by default, and has simple support for XPM. The GIF and PNG options may not be available if they weren't selected when the program was configured.

-t, --paper-size=papersize

Set the initial size of the bitmap to be one of the paper sizes returned by --query=paper. This is useful either to make sure that there is enough room on the initial bitmap, to avoid the warning above, or, along with the --process=nocrop option, to force the output bitmap to be a certain size.

-v, --verbose=[quiet|silent]

Quiet mode suppresses some chatter, and silent mode suppresses chatter, and does not display warnings or errors either.

-V, --version

Display the version number and compilation options, and exit.

-X, --process=[keyword-value-list]

Specifies the processing to be done. Keywords are as follows:

dvi and nodvi : enable or disable processing of the DVI file. If disabled, we do not require a DVI file to be present on the command line. The nodvi option is useful with some of the --query options.

postamble and nopostamble: enable or disable processing of the DVI postamble. If dvi2bitmap is called to invoke a non-seekable device such as a pipe, you should disable processing of the postamble. Disabling the postamble processing is incompatible with the --query options which examine the fonts in the file. By default, both the DVI body and the postamble are processed.

--process=options: shorthand for --process=nopreamble,nodvi,nopostamble. Only the options are examined.

blur and noblur: if true, blurs the bitmap, making a half-hearted attempt to make a low-resolution bitmap look better. This really isn't up to much -- if you have the fonts available, or are prepared to wait for them to be generated, a better way is to use the --magnification option to magnify the DVI file, and then the --scale option to scale it back down to the correct size.

transparent and notransparent: if true, this makes the output bitmap have a transparent background, if that's supported by the particular format you choose using option --output-type

crop and nocrop: if true, specifies that you want the output bitmap to be cropped. This is true by default, so you'll most often use the crop=false to specify that you do not want the output cropped (for example, if you're using the --paper-size option and want the output to stay the specified size).

By default, bitmaps are not blurred, are cropped, and are transparent if possible.

For PNG files, the output bitmap uses a palette plus an alpha channel; these are calculated in such a way that if you display the resulting bitmap on the same colour background as dvi2bitmap was using (which is white by default, but can be specified using the ) then the result should look identical to the result with no transparency information, but probably progressively worse the further the background moves from this. I suppose, but can't at present check, that this implies that you should choose a mid-grey background colour when making such transparent PNGs. I'd welcome advice on this point.

2.2 DVI specials

dvi2bitmap recognises several DVI special commands, and emits a warning if it finds any others.

The syntax of the special commands is

\special{dvi2bitmap <special-command>+ }

There may be one or more <special-command> sequences within a single special.

The <special-command> which the program recognises are:

default

Makes other special-commands in this same special affect defaults. See those commands for details.

outputfile <filename>

The output file used for the current page will be named filename.gif (if the output type were `gif'). A filename extension will be added if none is present, or if it does not match the output type selected.

If the default command has been given, then this instead specifies the default filename pattern, and the `filename' should contain a single instance of either %d or #; if there is no such instance, one will be implicitly added at the end.

The %d is precisely analogous to the behaviour of the option. However it is actually rather tricky to get an unadorned percent character into a TeX special, unless you play catcode tricks, and this is why you may alternatively include a # character to indicate where the page number should go. In fact, since it is also rather tricky to get a single # character in a special, any immediately following # characters are ignored. Thus the recommended way of specifying this special is through something of the form

\special{dvi2bitmap default outputfile myfile-#}

using the # form, and letting the file extension be controlled by the output type which is actually used.

absolute

Affects the crop command.

crop <side> <dimen>

Crop the bitmap on the current page so that the specified edge of the bitmap is <dimen> points away from the bounding box of the blackened pixels. <side> may be one of `left', `right', `top', `bottom' or `all', referring to the corresponding edge, or all four edges at once. If the default command has been given in this special, then this pattern of cropping is additionally made the default for subsequent pages. If the absolute command has been given, then the crop position is set at <dimen> points from the appropriate edge of the `paper'.

The -c and -C command-line options (2.1 Options) have the effect of setting initial defaults. In the absence of either of these, the initial crop is exactly at the bounding box.

default imageformat <format>

Set the default image format, which should be one of the keywords `xbm', `xpm' `gif', `png'. This is equivalent to specifying the image format through the -t option (section 2.1 Options).

The keyword is just imageformat, but you must specify the default keyword when you specify imageformat; this is for consistency, and makes it clear that this is setting a default format rather than setting the format only for the next image (that's not implemented at present, but could be added).

default foreground|background <red> <green> <blue>

Sets the (default) foreground and background colours for text. This works, as long as you specify the colour change before any text is output, since you can't, at present, change the colours after that. Specifically, you can't change the colours for a fragment of text in the middle of a page; for this reason, and as with imageformat you should at present always include the default keyword when using this special. The integers must be in the range [0,255], and can be specified in decimal, octal or hex (ie, 127=0177=0x7f).

strut <left> <right> <top> <bottom>

This places a `strut' in the generated file. Using the usual TeX \strut won't work: that would leave the appropriate space when TeXing the file, but that space doesn't explicitly appear in the DVI file (which is just a bunch of characters and locations), so when dvi2bitmap fits its tight bounding box to the blackened pixels in the file, it knows nothing of the extra space you want.

The `strut' special forces the bounding box to be at least `left', `right', `top' and `bottom' points away from the position in the file where this special appears. All the dimensions must be positive, and they are floats rather than integers.

If you wanted to set a page containing only the maths `${}^\circ$' (why, is another matter), dvi2bitmap would normally make a tight bounding box for the bitmap, so that you'd get an image containing only the circle (unless other crop options were in force). If, in this case, you put in a special such as \special{dvi2bitmap strut 0 2 10 2.5}, you would force the bounding box to come no closer than 0pt to the left of the position in the file where this special appears, 2pt to the right, 10pt above and 2.5pt below.

A useful bit of TeX magic is:

{\catcode`p=12 \catcode`t=12 \gdef\DB@PT#1pt{#1}}
\def\DBstrut{\strut\special{dvi2bitmap strut 0 0 
\expandafter\DB@PT\the\ht\strutbox\space\expandafter\DB@PT\the\dp\strutbox}}

Once you've done that, the command \DBstrut will put an appropriate strut in the output.

mark

This sets a `mark' in the generated file, which is reported when you specify --query=bitmaps (see ). Normally, --query=bitmaps writes out the horizontal and vertical size of the generated bitmap. If use of this special has placed a `mark' in the bitmap, however, then the --query option also reports the position of that mark, as a position within the bitmap, such that the top-left corner of the bitmap has coordinates . For example, after

\noindent\special{dvi2bitmap mark}Hello

the command line

dvi2bitmap --query=bitmaps foo

might report

Qbitmaps foo-page1.png 80 14 -1 10

indicating that the bitmap is 80 pixels wide by 14 high, and that the reference point, after cropping, is at position . The `-1' is because the mark appears to the left of the `H' of `Hello' (and the `H' probably has some negative offset), and the `10' indicates that the baseline of this text is 10 pixels from the top of the bitmap; this latter information might be useful when working out how to position this bitmap within a generated HTML file. See 3.4 Using marks to position bitmaps for a discussion of how to do that.

Both here and in the support for the `strut' special, there is a great deal of scope for off-by-one errors; also it's unclear what is the best interface to this functionality, so it's possible that this might change in subsequent versions. The author welcomes comments.

unit <u>

The units in the `strut' and `crop' specials are by default in TeX points. You may switch to a different unit with the `unit' special. The specifier `u' gives a unit name, which may be selected from the set of units TeX knows about (`pt', `bp', `cm', and so on), plus `pixels', and `dvi' to select DVI file units (usually the same as `sp'). If the `default' qualifier is present, this setting applies to subsequent special strings as well.

For example, the pair of commands

\special{dvi2bitmap default outputfile trial-# unit pc crop all 5}
\special{dvi2bitmap absolute crop left 5}

will change the output filename pattern for the rest of the DVI file, and set a 5pc margin round the bounding box. The current page, however, will have a left-hand crop five points in from the left hand side. Remember that TeX's origin is one inch from the left and the top of the paper, and it is with respect to this origin that the program reckons the absolute distances for the cropping.

2.3 Exit value

Exits with a non-zero status if there were any processing errors. Having no fonts present counts as a processing error.

If there is at least one font present, then missing fonts will be replaced by the first cmr10 font it finds, or a more-or-less randomly chosen alternative if that font is not used at all. The program will produce a warning if the -q option is not present, but it will return with a zero (success) status.

Exception: If the -n option (see 2.1 Options) is present, then the program returns success only if all fonts are present.

2.4 Examples

Basic usage examples.

% dvi2bitmap --resolution=110 --magnification=2 --scale=2 \
--output-type=gif hello.dvi

This converts the file hello.dvi to a GIF bitmap. It first sets the magnification factor to 2, so that the program uses a double-size font (eg, .../cmr10.220pk), then scales the bitmap down by a factor of 2 to obtain a bitmap of the correct size.

% dvi2bitmap -n -Qf --resolution=110 --magnification=1.5 \
--verbose=quiet hello.dvi
Qf cmr10 165 110 1.5 localfont

This reads the DVI file to find out what fonts are required, but does not process it further. It then tries to find the fonts, fails, and produces a list of parameters which could be used to generate the font files.

See also 2.5 Finding and generating fonts, and see 3 Usage notes for more elaborate examples of use.

2.5 Finding and generating fonts

2.5.1 Finding fonts

The program searches for fonts using a number of mechanisms.

  1. The -fp option (see above) specifies a colon-separated list of filename templates which should be searched for font PK files. If this is given on the command line, it overrides...

  2. The DVI2BITMAP_PK_PATH environment variable, if defined, specifies a colon-separated list of filename templates which are to be searched for PK files.

  3. If the program cannot find fonts using the environment variable, and if it was configured with support for the kpathsea library (see ), then it should find PK files using the same mechanism other DVI processors use.

  4. dvi2bitmap can be configured to use a script to find fonts. If the program was not configured to use kpathsea or the search fails, then the program invokes a script which knows where to find font files, given a search pattern, and which returns a single line containing a discovered font filename. See .

The third method is the ideal -- you should build dvi2bitmap using the kpathsea library if possible (see 5.1 Obtaining the kpathsea library for how to obtain it): it is because other DVI-processing programs like dvips and xdvi are built with the kpathsea library, that you normally never have to worry about where fonts live. The kpathsea library is generally integrated with the font-generation commands, and can be queried using the kpsewhich command.

There are one or two possible wrinkles with the third method. The path-searching library is very powerful and flexible, but it is possible to be tripped up by its configuration file.

Firstly, the program has to find the configuration file. The program should sort this out for itself at configuration time, but it is possible that you might have to give it some help. If you specify the TEXMFCNF environment variable, setting it to the directory which contains your TeX installation's texmf.cnf file, then this overrides the program's notion of where the configuration should be. You can find this file using the command kpsewhich cnf texmf.cnf.

Secondly, it's possible to break the configuration file. Certain TeX distributions (the ones that came with early RedHat 6.x distributions are ones I know about) are broken in an unfortunate way. See 2.5.2 Not finding fonts for a discussion.

2.5.2 Not finding fonts

It can sometimes happen that dvi2bitmap fails to find fonts, successfully calls mktexpk to build them, but then still fails to find them, even though mktexpk has put them where they should be. There are (at least) three possible reasons for this.

If you are using the kpathsea library, there might be some misconfiguration which is confusing it. You can trace kpathsea's deliberations in massive detail by giving the option -ggp ().

Perhaps you do not have the kpathsea library installed, or have disabled it, but you have requested that font-generation be enabled (see ). What happens in this case is that mktexpk successfully builds the fonts, and installs them in the correct place, where `correct place' means `the place where kpathsea would find them'; you're not using kpathsea, so no fonts for you. What you have to do in this case is work out where the `correct place' is (kpsepath and kpsewhich can help here), and specify that place using either the -fp option or the DVI2BITMAP_PK_PATH variable, as above (this is confusing, I know, but more-or-less unavoidable, since we are here trying to do kpathsea's job, without kpathsea).

I think it is also possible to fall victim to a race condition, where the font is built successfully, but the program looks for it in the correct place before the font is fully flushed to disk, or (mumble) something like that. Simply running dvi2bitmap a second time seems to work OK. I'm not sure precisely what's going on here, and I'd welcome more precise observations, here.

Another, slightly nastier reason is as follows.

Some texmf.cnf files declare the location of the user-writable font directory though a setting like

VARTEXFONTS=$SELFAUTOPARENT/var/lib/texmf

whereas others have something like

VARTEXFONTS=$TEXMFLOCAL/fonts

Now, $SELFAUTOPARENT is a variable which is set by the kpathsea library to be the grandparent directory of the executable which uses the library. So, for /usr/bin/{tex,latex,mktexpk,...}, it's /, but if your dvi2bitmap binary doesn't live with the other dvi-ware then its $SELFAUTOPARENT will be different, so that dvi2bitmap will look for fonts in a different place from the place where mktexpk put them when it successfully generated them.

I would argue fairly strongly that having the VARTEXFONTS directory depend on the location of the dvi-ware executables is a very silly thing to do. This was the case in the teTeX distribution which came with RedHat 6.0, though this was fixed pretty rapidly. If you've fallen foul of this, then you can either

I'd much prefer the first alternative, myself.

A third option is to get dvi2bitmap to work around the problem, by telling it to claim to be some program which is installed along with the other dvi-ware. You do this with the --enable-fake-progname option to the configuration script (see ).

2.5.3 Generating fonts by hand

If you didn't enable automatic font-generation, or if you did and something went wrong, you might have to generate fonts by hand. You need to look at the documentation for your TeX system, specifically the mktexpk and MakeTeXPK scripts (one of which might be just an interface to the other).

See the discussion of the `make test' script in 2.5.1 Finding fonts. Also, note that the option -Qg, given to dvi2bitmap, displays the font-generation commands which would be required to build the fonts missing from the specified DVI file. These are the commands which dvi2bitmap would employ to generate these fonts, when automatic-font-generation is enabled.

Since dvi2bitmap's default resolution is 72 dpi, as opposed to the usual printer resolution of 300 or 600 dpi, you are unlikely to have suitable fonts on your system, and will need to generate them. The program will generate these automatically, if it was configured with support for that (see ); if it wasn't configured with that support, or if the automatic font generation fails, you might need to generate the fonts by hand.

How you generate fonts depends on your TeX distribution. As explained in 2.4 Examples, you can determine which fonts you need using the -Qf option. The teTeX and TeXLive TeX distributions include scripts to generate fonts for you; if you have a different distribution, there might be a similar script for you to use, or you might have to do it by hand. In the case of teTeX, the command you'd use in the example above would be:

% MakeTeXPK cmr10 165 110 1.5 ibmvga

This would generate fonts using the ibmvga Metafont mode, using a base resolution of 110 dpi (the default for that mode), at a magnification of 1.5 times, giving a resultant resolution of 165 dpi.

If you're using the TeXLive distribution, the equivalent command would be:

% mktexpk --mfmode ibmvga --mag 1.5 --bdpi 110 --dpi 165 cmr10

If you want to use the same mode as you use for printing documents, then the mode localfont should do the right thing. Otherwise, and probably better if these images are intended for the screen rather than paper, you could use a more specialised mode such as ibmvga, which has been tweaked to be readable at small resolutions. See the file modes.mf somewhere in your metafont distribution for the list of possibilities.

After you have created the fonts, try giving the command

% kpsewhich pk cmr10.165pk

to confirm that TeX and friends can find the new fonts, and that your dvi2bitmap environment variable is set correctly. This command is part of the kpathsea distribution, rather than the core TeX distribution, so may not be present on your system.

2.5.4 Font-string templates

The search-path and font-finder routes use font-string templates. Here, the components of a font file name, or a font-finding command, are specified using placeholders like %f. You may use

%M mode (eg. ibmvga)
%f font name (eg. cmr10)
%d dpi (eg. 330)
%b base dpi (eg. 110)
%m magnification (eg. 3)
%% %

Thus, using these values as an example, if one of the entries in DVI2BITMAP_PK_PATH were /var/tmp/%M/%f.%dpk, this would expand into /var/tmp/ibmvga/cmr10.330pk. Alternatively, if we had given the font-finder script as /usr/local/teTeX/bin/kpsewhich pk %f.%dpk, the dvi2bitmap would have executed the command .../kpsewhich pk cmr10.330pk, which would have returned with a suitable font path.

3 Usage notes

3.1 Good choices of fonts and scaling

There is a certain amount of subtlety in choosing fonts and resolutions for maximum readability.

The fonts that dvi2bitmap (currently) uses by default are from the cmr family, and generated using Metafont mode ibmvga, chosen because its design resolution, of 110 pixels to the inch, is approximately right for bitmaps viewed on the screen. This is not, however, necessarily the optimal choice in all circumstances.

You can produce some simple antialiasing by magnifying the output bitmaps then scaling them down, so that:

% dvi2bitmap --magnification=2 --scale=2 myfile.dvi

doubles the size of the bitmaps, then halfs it, effectively blurring it in the latter stage. This works quite well. You don't necessarily get better results with larger factors (though it does, of course, depend on the situation), because Metafont already does some work to make the characters easier to read, and I suspect that excessive antialiasing merely frustrates this.

If you choose a different Metafont mode, it can make a difference. In your TeX distribution, there should be a file called modes.mf, containing a large collection of Metafont font-generation modes (look for it using kpsewhich modes.mf if you have that command), and there are several modes in this set which have resolutions in the 70 to 200 range, which are therefore about the right size to be useful in this context. You're probably aiming for a resolution of around 100 pixels per inch, if you want the text in the output bitmap to be around the same size as the other text on your monitor. For example, try the ncd and nec modes:

% dvi2bitmap --magnification=2 --scale=2 --font-mode=ncd --resolution=95 try.dvi 
% dvi2bitmap --scale=2 --font-mode=nec --resolution=180 try.dvi 
% dvi2bitmap --magnification=2 --scale=4 --font-mode=nec --resolution=180 try.dvi

Note that the declared resolution must match the font mode -- the default resolution of 110 is designed to match the default mode of ibmvga. Also the nec mode, because its base resolution is large anyway, only needs to be scaled down to get adequate antialiasing.

It should be possible to create a Metafont mode specifically for dvi2bitmap applications. That might be a useful project for someone!

Another thing to look at is whether changing the font family can help. The Computer Modern family is, of course, designed for paper. The Concrete Math family, though also designed primarily for paper, has features which make it particularly suitable for this application. The FAQ article which discusses maths font choices remarks that

Since Concrete is considerably darker than Computer Modern, this variant may be of particular interest for use in low-resolution printing or in display-oriented applications such as posters, transparencies, or online documents.

As well as this, these fonts have rather simpler outlines than Computer Modern and they are rather more upright, both of which make them more robust to being rendered at rather small resolutions.

You can use the concrete maths fonts simply by adding the declaration

\usepackage{concmath}

to the preamble of your LaTeX document. In tests, the best configuration for clarity in a bitmap appeared to be a document using the concrete maths fonts, plus the dvi2bitmap invocation

% dvi2bitmap --magnification=2 --scale=4 --font-mode=nec --resolution=180 try-cc.dvi

Any observations on this topic would be warmly appreciated.

Many thanks to Doug du Boulay at titech.ac.jp for raising this issue, for thus prompting me to discuss the various options, and for then doing the critical testing work.

3.2 Using dvi2bitmap in a pipe

dvi2bitmap is perfectly happy reading DVI files from a pipe, so that

cat myfile.dvi | dvi2bitmap --pipe -

will work perfectly well. Since the program knows that the standard input -- indicated by the - argument to dvi2bitmap -- is not seekable, the option --pipe is actually redundant. This is not by itself particularly useful, since TeX is not written to send its DVI output into a pipe.

If, however, you make a `named pipe' beforehand, using the Unix mkfifo command (a FIFO, or first-in-first-out, is the other name for such an object), then TeX can be persuaded to send its output there.

% mkfifo myfile.dvi
% ls -l myfile.dvi
prw-r--r--  1 norman  admin  0 Aug 12 00:18 myfile.dvi
% latex myfile >myfile.stdout &
% dvi2bitmap --pipe mkfile.dvi

Here, we create the FIFO using the mkfifo command; looking at it, we see that the first character on the ls line is a p, indicating the type of object it is. We start (La)TeX going in the background (achieved by the &), putting its chatty output into a file, and it merrily writes into the `file' myfile.dvi. Immediately afterwards (we've shown this on two lines, but the two commands could be run together with only the & separating them) we start dvi2bitmap, telling it to read from the named pipe. The pipe effectively synchronises the two processes, so that if there is nothing to read, dvi2bitmap is briefly suspended, and if the pipe is full, LaTeX is suspended. After this performance, the DVI file, myfile.dvi ends up zero size again, and the process can be repeated.

You can go further than this, and use a FIFO for LaTeX's input, too:

% mkfifo myfile.tex myfile.dvi
% cat foo.tex >myfile.tex & \
latex '\input myfile.tex' >myfile.stderr & \
dvi2bitmap --pipe myfile.dvi

(the trailing backslashes indicate that this second set of commands is all on one line). The rather odd form of LaTeX invocation (note the quotes) stops TeX from peeking at the file, looking for the magic %& line which can tell it which format to use; since the input is a pipe, it's unseekable, so we must use this form, or else LaTeX fails.

3.3 Processing many bitmaps

If you have a large number of fragments of TeX to process, it is best not to invoke dvi2bitmap for each one individually. Also, the program does not (yet) allow you to specify more than one DVI file as input. In this situation, it is best to generate an input TeX or LaTeX file which contains all of the text you wish to process, with one fragment per page.

For example, the following can help:

\documentclass{article}
\pagestyle{empty}
\special{dvi2bitmap default imageformat png}
\newcommand{\neweq}[1]{\vfil\break\special{dvi2bitmap outputfile #1.png}}
\begin{document}

\neweq{index-html-alpha}
$\alpha$

\neweq{index-html-aprime}
$A'=(0,\alpha,0,0)$

[...]

\end{document}

That includes a special to make PNG the default output format, and defines a command sequence, \neweq which simultaneously forces a new page and inserts a special to name the output file. A script which generates a file like this and then looks for the resulting bitmaps, with known names of course, can run very efficiently. Combining that with the techniques in 3.2 Using dvi2bitmap in a pipe can work wonders.

3.4 Using marks to position bitmaps

When including small images in an HTML page, it can be difficult to get the images to line up with the rest of the text, because a text with descenders (characters which go below the line such as `p' or `g') cause the image to be offset from the text line. You can use the `mark' facility to tell you how much you need to offset such an image so that it lines up properly with the surrounding text.

For example, consider the following usage:

% cat temp.tex
\nopagenumbers
\noindent\special{dvi2bitmap mark}%
Hello, this is dvi2bitmap
\bye
% tex temp.tex
This is TeX, Version 3.14159 (Web2C 7.3.11)
(./temp.tex [1] )
Output written on temp.dvi (1 page, 240 bytes).
Transcript written on temp.log.

So, a simple test file with a single line in it, with descenders (the `p'). The `mark' special goes at the beginning, following \noindent. This is important, otherwise the point that is marked is the very top-left of the image, not the bottom-left.

The output with --query=bitmaps is:

% dvi2bitmap --verbose=quiet --query=bitmaps temp
Qbitmaps temp-page1.png 163 14 -1 11

...where verbose=quiet has been used to turn off the usual chatter. It tells us that the bitmap as a whole is 14 pixels deep, and that the mark, which is on the TeX baseline, remember, is at position (-1,11) relative to an origin at the top-left of the bitmap; or in other words there's 3 pixels of space between the TeX baseline and the bottom of the image. We therefore know that we need to offset the image by three pixels to make it line up properly.

There are several ways to do that, but one way is to use per-element CSS properties, like this:

% dvi2bitmap --verbose=quiet --query=bitmaps temp | awk  
'{printf "<img src=\"%s\" style=\"margin-bottom: %dpx\"/>\n", $2,  
$6-$4}'
<img src="temp-page1.png" style="margin-bottom: -3px"/>
%

So that's generated an <img> element which has the correct `src' attribute (from column 2 of the Qbitmaps line) and the correct offset (column6 - column4). That uses awk, but if you're generating your HTML pages with something like Perl or Python (substantially more sensible than awk...!), say, you could do an analogous thing with the dvi2bitmap output, and put the generated <img> elements in the correct places in the output HTML file.

4 The libdvi2bitmap library

The main bulk of the code which implements dvi2bitmap is in a library, and the program itself is a rather thin wrapper on top of this. This library is intended to be usable for other applications.

The library is written in C++, and provides an abstraction of DVI files, PK font files, Bitmaps, and various other objects used to build these ones. By default, the build procedure creates both static and dynamic libraries.

The library API is extensively documented in the doc_libdvi2bitmap/ directory of the distribution.

5 Building and installing dvi2bitmap

The package uses a automake/autoconf/libtool build system. Building should therefore be simple:

% ./configure
% make
% make install

but see the configuration options below.

By default, both a static and a dynamic library are built. If there is some reason why building the dynamic library fails on your platform, configure using --disable-shared and you'll build a static library only.

It's a good idea to run (cd test;make) as well. See 2.5.1 Finding fonts.

To install, just copy the executable dvi2bitmap wherever you want it to live.

You can customise the program using flags to the ./configure command:

--with-kpathsea and --without-kpathsea

If you have the kpathsea library (see 2.5.1 Finding fonts) but don't, for some reason, want to use it, then give the configure option --without-kpathsea. By default, the configuration enables use of the library if it is installed (that is, if the kpathsea include files and library are somewhere the compiler will find them. If kpathsea is disabled (by default or by request), then fonts will not be generated by default.

If you have the kpathsea library, but it is not in the standard place, then you can provide an argument to the --with-kpathsea option giving the name of a directory below which are directories include and lib, containing the required kpathsea include files and library. If you don't have the kpathsea library available, see below (5.1 Obtaining the kpathsea library) for notes on obtaining it.

--disable-texmfcnf

The kpathsea library finds its configuration files in two ways, either automatically if it is installed in the same directory as the rest of the TeXware, or using the TEXMFCNF environment variable. The dvi2bitmap program sets the latter variable internally, unless it finds it already set. If this will be inconvenient, you can suppress this behaviour by providing the flag --disable-texmfcnf, or equivalently --enable-texmfcnf=no.

--enable-fontgen

The program can attempt to generate fonts, and will do so using the MetaFont mode ibmvga, which has a resolution of 110 dots-per-inch.

You can give an argument to this command, which specifies a command-line which will build and install a required font, and return its path on standard output. This uses the font-string template described in 2.5.4 Font-string templates. You could duplicate the default (the mktexpk script if present) with the option

--enable-fontgen='<path>mktexpk --dpi %d --bdpi %b --mag %m --mfmode %M %f'

The default for this option is `on' -- the program will attempt to generate fonts. Do note, however, that if the kpathsea library is not enabled, then the program will not be able to find the fonts it generates, unless you configure it correctly using either -fp or DVI2BITMAP_PK_PATH (see 2.5.1 Finding fonts).

If you wish to disable this automatic font generation, give the option --disable-fontgen. Note that this does not completely disable font generation -- it merely sets the default for font generation to `off', and it can be switched back on again using the option -fG.

If you wish to change the default mode, you can do so using the option .

--with-fontgen-mode=mode,res

If you wish to change the default parameters for font-generation, you can set both the Metafont mode and resolution using this option. For example, the option --fontgen-mode=pcprevw,118 will make pcprevw, which has a resolution of 118 dpi, the default MetaFont mode. Note that the resolution you specify must match the mode: see file modes.mf for a list of modes and resolutions (use kpsewhich mf modes.mf to find this). You can change the resolution and mode on the fly using the -fm and -r options to the compiled program (2.1 Options).

--with-fontfinder

This specifies a command to run to find fonts. It is preferable to use the kpathsea library if possible, but if this is difficult, then you can specify a script to run to find fonts. This uses the font-string template described in 2.5.4 Font-string templates. To use the standard kpsewhich command, for example, you could give the option

--with-fontfinder='/usr/local/teTeX/bin/kpsewhich pk %f.%dpk'
--enable-mktexpk and --enable-maketexpk

In the default configuration, the program will generate missing fonts using one of the standard scripts present in most TeX distributions. The configuration process looks first for mktexpk then MakeTeXPK, and uses whichever it finds first. If you have both scripts but wish to use MakeTeXPK for some reason, you will have to give the option --disable-mktexpk; if you wish to disable both, you will have to give --disable-maketexpk as well. Both options take an optional argument giving the path to an alternative script with the same calling interface.

--with-png (default: enabled)

If you give this option, and if the PNG library is installed (needs a version after 0.96), then the program will be compiled with support for PNG bitmaps as an output format. You can obtain the PNG library from the PNG home page. You can disable the use of PNG with the option --without-png.

--enable-gif (default: disabled)

The program generates only XBM bitmaps by default. If you want it to be able to generate GIFs, then give the configure option --enable-gif. The GIF format is the copyright of CompuServe. As far as I understand it, one does not need a licence from CompuServe if one is distributing non-commercial, not-for-profit software, such as this. You probably shouldn't enable GIF support when you build this program unless you're in that category as well. But don't listen to me: there's a much fuller account of the whole sorry business in the Graphics File Formats FAQ (HTML).

--enable-fake-progname

This option enables a workaround which allows dvi2bitmap to have the expected behaviour when (a) you do not install dvi2bitmap along with the other dvi-ware, and (b) your texmf.cnf file has VARTEXFONTS (or a similar variable) depending on one of the SELFAUTO... variables (such a texmf.cnf file is probably broken, but that may not be your problem, or within your power to fix). This option makes dvi2bitmap claim to be a different DVI-reading program which is installed in the standard place. See 2.5.2 Not finding fonts for discussion. The configuration script uses the location of the xdvi program by default, but you can override this by giving the full path to an alternative as an argument to this option (that is, --enable-fake-progname=/path/to/dviprog).

Since this uses undocumented behaviour of the library (`use the source, Luke!'), you almost certainly shouldn't enable it unless you have to.

--with-path-seps

The default configuration is for Unix, and uses the Unix defaults for filesystem path and search path separators. If you are building it on some other architecture, you can alter the defaults by giving a two-character argument to this option, giving the two separators in order. For example, the arguments appropriate for DOS would be

--with-path-seps='\;'

The ./configure command without any options is equivalent to ./configure --with-kpathsea --with-png --enable-mktexpk (meaning that kpathsea and PNG output will be enabled if library support for them is found).

The program builds successfully on (at least):

Platform Version Compiler
powerpc-apple-darwin6.6 (MacOS X, 10.2.6) 0.11b1 g++ 3.1 20020420 (prerelease)
sun-sparc-solaris2.9 0.11b1 CC: Sun WorkShop 6 update 2 C++ 5.3 2001/05/15
alphaev67-dec-osf5.1 0.11b1 Compaq C++ V6.5-014
i686-pc-linux-gnu (RedHat 7.3) 0.11b1 g++ 2.96
i686-pc-linux-gnu (RedHat 7.3) 0.10 gcc 2.96
i686-pc-linux-gnu (RedHat 6.2) 0.10b1 egcs-2.91.66
powerpc-apple-darwin6.4 (MacOSX 10.2) 0.10 g++ 3.1 20020420 (prerelease)
sparc-sun-solaris2.8 0.10b1 egcs-2.91.66
alphaev56-dec-osf5.0 0.10b1 egcs-2.91.66
i686-pc-linux-gnu (RedHat 6.2) 0.9-7p1 egcs-2.91.66
powerpc-unknown-linux-gnu (Mac mklinux DR-0.3?) 0.9 egcs-2.90.25 980302 (egcs-1.0.2 prerelease)
sparc-sun-solaris2.7 0.9 egcs-2.91.66
sparc-sun-solaris2.7 0.9 gcc 2.8.1
sparc-sun-solaris2.7 0.9-6 WorkShop Compilers 5.0 98/12/15 C++ 5.0
alpha-dec-osf4.0f 0.9-6 Compaq C++ V6.2-024 for Digital UNIX V4.0F
i386-pc-solaris2.6 0.9-7p1 gcc v2.8.1/libstdc++ v2.8.1.1

The `version' column is the last version which was actually tested on that platform/compiler combination. Reports of compilations on other platform/compiler combinations gratefully received.

It should be written in standards-conforming C++, so if it doesn't build then (1) it's not as conformant as I think it is (in which case please tell me), (2) your compiler is not as conformant as you think it is (in which case please don't tell me), or (3) you need to invoke some magic to get the compiler to be conformant (in which case tell me, if there's something I can do in the autoconfigure script).

You can override the C++ compiler the configure script will choose by setting the environment variable CXX, either via

% CXX=cxx ./configure

or

% env CXX=cxx ./configure

depending on your shell.

Run regression tests with (cd test;make) in the build directory. This includes a separate whole-program test which additionally gives advice about setting environment variables. You can run this script separately with the command (cd test;make pathtest)

Regression test 6 currently fails to link when using Compaq cxx, for some arcane C++ reason I have yet to diagnose. The whole-script test mentioned above works, though.

5.1 Obtaining the kpathsea library

Not all TeX distributions install the kpathsea library, even though they install applications built with it, and the texmf.cnf configuration file which controls it.

If the library does not appear to be in your distribution, then you can obtain and build it yourself. The library is distributed as part of the web2c (Unix TeX source) distribution, which you can find at ftp://ftp.tug.org/tex/web2c.tar.gz, or mirrored on CTAN sites (for example at http://www.tex.ac.uk in directory systems/web2c).

Take a copy of the library (this is a big distribution), and unpack it. Go into the kpathsea directory and do the usual `./configure; make; make install' routine. With (some?) older distributions of the library this appeared not to work, and you had to go to the parent of the kpathsea directory, delete the web2c directory (which is the bulk of the distribution), then configure and build it as usual, ignoring the warnings about the missing main texmf tree.

6 Bugs, extras, and further developments

To report bugs, please send to [email protected] a brief description of the problem; a minimal TeX file which reproduces it; some indication of the machine you're running on (uname -a is good); and the output of dvi2bitmap -V, which shows the options you have enabled.

See the TODO list in the distribution, for the list of things I at least would like to see added to the code.

Bright ideas, fixes and (especially) implementations, cheerfully received.

In the .../extras directory of the distribution is a script img-eqlist.pl, which transforms a file of LaTeX fragments into a LaTeX file, keeping track of filenames, and avoiding generating duplicate bitmaps for duplicated maths.

7 References and acknowledgements

CTAN, the Comprehensive TeX Archive Network, is the repository of TeX and LaTeX documentation. The archive is mirrored in numerous places, but the UK node is at http://www.tex.ac.uk.

DVItype and PKtoPX are two programs Donald Knuth intended as model DVI and PK file readers, and as containers for the canonical documentation of the DVI and PK file formats. They might be available as part of your TeX distribution, but are also available on CTAN, in /tex-archive/systems/knuth/texware/dvitype.web and /tex-archive/systems/knuth/pxl/pktopx.web.

The DVI Driver Standard, Level 0 is available on CTAN, in directory /tex-archive/dviware/driv-standard. This incorporates sections of the DVItype documentation. This program claims to conform to this standard: if it doesn't, please let me know.

Thanks for bug reports and other suggestions to Eitan Gurari (heroic tester), Oliver Schurr and Oleg Bartunov ([email protected]).

Yamabe Kazuharu ([email protected]) supplied the writer for XPM bitmaps.

Appendices

A Maths and SGML/HTML

A.1 LaTeX maths within HTML

The real issue here (for me at least) is rendering equations within an HTML document. There are several tools available which can do that with different trade-offs. The most popular method is to write the equations in a LaTeX document, process it, and then hoik the equations out of the resulting DVI file somehow (typically using dvips and a postscript to gif converter), and display them on the web as gifs. The big disadvantage with this is that you get an awful lot of gifs, and the conversion is rather inefficient.

All this hassle should become irrelevant once we get browsers which can render MathML directly.

There are reviews of the problems, and some of the tools, in articles Maths Typesetting for the Internet, and Comparative Review of World-Wide-Web Mathematics Renderers.

LaTeX2HTML is the granddaddy of these translators -- it parses the LaTeX using Perl, and spits out HTML, turning maths into gifs. It's very robust by now.

John Walker's textogif is a Perl program which orchestrates the various tools to do the conversion via postscript, once you've generated the DVI file. It works, but it's terribly slow, which was the motivation for this program.

TeX4ht (TeX for Hypertext) uses TeX's own parser, but still produces equations as gifs. TeX4ht can also emit MathML from LaTeX. The TeX4ht documentation has a useful collection of resources. There's an alternative location for TeX4ht at TUG.

tth: TeX to HTML translator (manual). tth translates LaTeX maths directly to HTML, with remarkable success and astonishing speed, and with good failure strategies. It works very sweetly, but (a) requires you to tweak your browser to have it map the symbol font appropriately, and (b) the resulting HTML can't be printed legibly. From the same source is TtHMML, which translates (La)TeX to HTML plus MathML.

nDVI is a DVI viewer plugin for Unix Netscape. This addresses the problem at the client end.

A.2 Other approaches to maths

A quite different approach is to use a different markup for maths, possibly requiring specialised client software. These other notations typically use semantic markup -- expressing the structure of the maths. At first sight, this seems preferable to LaTeX's presentational markup, but its weaknesses for authoring are exposed (I feel) when you realise that maths is not as closed and unambiguous a language as computer scientists feel it ought to be. Semantic markup's strength is in interfaces with computer algebra systems, and databases -- Abramowitz and Stegun would be ideal in this form! The major dislocation between the two approaches is what makes conversion from presentational to semantic markup so easy. In passing, I'll note that MathML has both a presentational and a semantic variant.

MINSE uses a server to render maths into gifs on the fly. It seems to work rather nicely, but works with its own semantic maths notation.

There is (was?) a project called Euromath, which includes a structured SGML editor. This project included a converter which could transform LaTeX to Euromath SGML.

OpenMath might be a successor to Euromath. It's an EC Esprit project which `proposes to develop standards for the semantically-rich representation of mathematics'.

GELLMU is a LaTeX-like markup language, intended to be easy to convert to SGML. Specifically, it is intended to support maths (and hence conversion to MathML) well.

The following are specifically concerned with maths in SGML, using either MathML or other maths DTD fragments.

WebEQ is a suite of Java programs which implement MathML. It's commercial.

TeXML is a gadget from IBM which converts XML to TeX via a DTD fragment. You transform your XML to an equivalent document marked up in TeXML, which you then separately transform to TeX.

EzMath is a Dave Raggett proposal for producing maths on the web. It uses yet another notation, and converts it to online form using a plugin (no printing, and Windows only, as of April 1999).

B TeX dimensions

When producing this program, I became terribly confused about the variety of dimensions which appear in DVI and PK files. is a summary of the sizes which appear, for the benefit of anyone else attempting a project like this. The reference [Dn] refers to section `' of the webbed DVItype document and [Pn] to section `' of the PktoPX document (see 7 References and acknowledgements).

If you feel I have misunderstood something here, or got one of the conversion factors wrong (I hate these!), please correct me.

Sizes in TeX
Context Description See
DVI preamble num, den: multiply a `DVI unit' by to obtain a length in units of [D17]
mag: DVI units are actually multiplied by [D17]
DVI font definition d: a design size, in DVI units. The nominal size of the font. [D18]
s: a `fixed point' scale factor, range , scaling d (see note). [D18]
PK preamble ds: the font design size in units of points. [P12]
hppp, vppp: number of pixels per point, times (see note). [P12]
Character tfmwidth: the width of the character (see note). [D37], [P9]
w, h: the width and height, in pixels, of the character pixel map. [P21]
hoff and voff: offset of the pixel map from the reference point. [P21]
dm, dx, dy: the pixel escapements. dm in pixels, dx and dy in pixels times (see note). [P21]
  1. s scales the design size, so that a font is actually used at times its normal size.

  2. hppp and vppp aren't used as sizes, but can be used to check you have the right fonts by comparing resolution, etc..

  3. tfmwidth is the `physical' size of a character, and is the only size that TeX uses in its calculations, and which the DVI reader uses when working out how far to move the reference point when it sets a character. This is defined in [P9] to be in units of FIXes, where one FIX is times the design size in points. [D37] describes how to multiply these widths by scaling factors without overflowing.

  4. The difference between the pixel escapements and tfmwidth is that the latter is a resolution-independent shift of the DVI reference point, and the former is the PK file's recommendation of the number of pixels the DVI processor should actually move. The DVI processor keeps track of the two reference points, and readjusts the pixel-based one when rounding errors move it too far from the resolution-independent one. See [D89] and [D91]; also [D40].

A few useful conversions are:

C Release notes

No changes from 1.0.