Mnemonic Math Object Model library (lib-mom)
General Info

Introduction
Screenshots
Mailing Lists and IRC
Alternative Browsers
Special Thanks

FAQ
Understanding Mnemonic
TODO list and ideas
Bug Reports


User Info

Download binaries
Platforms
Compiling Mnemonic
Other useful software


Developer Info

Core
Message modules
Library modules
Object modules
Coding Guidelines
Browse Source
Using CVS


View with any browser

Website questions to:
webmaster@mnemonic.org

Mnemonic questions to:
disc@mnemonic.org

 

Overview

In full analogy to the Document Object Model library, the Math Object Model library contains the classes necessary to represent the structure of a mathematical expression in terms of C++ objects. It is, to a large extend, based on the way TeX stores mathematical expressions in so-called mlists (see the publically available TeX sources for more details).

The lib-mom is not concerned with the actual parsing of an input file into the lib-mom classes (just as lib-dom does not do any parsing but leaves that to separate parsing modules). Also, lib-mom does not do any conversion of the internal representation of the mathematical expression to a collection of boxes for the layout engine (just as lib-dom does not do any typesetting of HTML documents). That task is left to lib-mathrender. This library is, in short, just a library to represent a mathematical expression in an efficiently accessible format.

$\sum_{n=1}^\infty \frac{\sqrt{x^2+y^2}}{\alpha}$

It is not clear whether this is a good idea. For MathML it makes a lot more sense to read the information directly from the DOM tree. If we stick to that idea we can implement a renderer immediately. For TeX things are much more complicated. In that case, however, we cannot even keep a static representation of the document in memory; it depends on the interpretation of all previous symbols.

The TeX interpreter will have several passes. We should probably not go all the way down to the dvi level, since that corresponds to the layout tree. But there is definitely some level at which all indirections have been evaluated and the true meaning of a symbol is known. We could use that in an internal representation. It is very wasteful on memory though, since all macros will have been expanded.

A better organisation is according to TeX groups. These are the relevant things when it comes to table of equivalents and so on. We'd have, for every group, the following info: all commands in terms of fundamdentals and commands of parent groups, current variables etc. In other words: the data stack. There are already C++ classes for this in tex++. From there, it would be relatively easy to convert to a lib-layout tree. As we are not going to implement this any further right now, it suffices to investigate how such an internal representation fits in with the lib-mom ideas.

** font renderers **

I guess that the thing we are really looking for is a way to instruct the font renderer what to display (this might seem a bit far removed from what I had in mind for lib-mom, but I don't think there is a good common denominator for TeX and MathML at a much higher level). For normal text a simple string suffices, but there will in general be layout instructions which do not easily fit in with lib-layout, or should not be part of that base library.

So we need some systematics to request a renderer of a font of a specific name as well as type: normal, symbols or extenders. For normal type we can hand it a string, but for symbols (which include operators and radicals) and extenders it is necessary to send more information. There should also be a way to fine-tune the layout by sending additional kerning instructions (though it is probably stupid to send much more data along).

Such renderers can use generic libraries to draw into bitmaps, but they should output boxes that go into the gtklayout tree (or whatever tree derived from lib-layout is currently in use). This means that we can have a oil-gtkfontrenderer module which takes care of producing normal gtktext boxes for simple text in a font that is available on the X server, and other boxes with bitmap rendered text for complicated fonts. You get access to a renderer for a given font by sending a requesting message and accepting the lib-gtklayout announced box (in order to avoid having to send broadcasts for every single character or word being rendered, it is probably a good idea to broadcast an ignore_geometry box. This will still be wasteful when there are very many font changes. Probably acceptable though (and the font renderer has to be able to store some information in the layout tree anyhow, which cannot be done without such ignore_geometry boxes anyway).

**interlude**

Entities: Mozilla uses a system in which entities are expanded to Unicode by the parser. They then convert these unicode values to actual glyphs later on. This is perfectly fine when indeed the intend of w3.org is that entities always represent unicode symbols. I guess it is. For mnemonic, with a generic parser, we would need the dtd to contain the mappings from entities to unicode values. In the standard DTD, that mapping is DEFINITELY not present. However, we can imagine using our own extended DTD for that. We need entity (ie `replacement text') handling anyway, the question is whether it is a good idea to reduce down to unicode. But since w3.org seems to focus on that, and since it implies a speedup of the renderer (we can do entity parsing in the parser and just switch on unicode values), let's adopt it.

Note that our DOM still uses 8-bit encodings. This will have to change. UTF-16 is probably the smarter choice, though UTF-8 might work. We need this very soon if we decide to use the entity to unicode parser mapping, as the PUA lies outside the 8-bit zone. How can we use C++ strings with UTF-16 values? (***search net, it is silly to invent the wheel again here, even though there is sample surrogate handling code at unicode.org).

Hopefully, even though the parser must understand different encodings, we can map lossless to an internal UTF-16 encoding.

*** So we need interfaces for the font renderers of various types. The normal font renderer has an interface to create gtklayout boxes which contain the info about a particular normal font, plus members which accept UTF-16 strings.

Symbol font renderers should accept more than that. UTF-16 is not enough, as we need info about sub/super and so on.

More economically, maybe all font renderers should inherit the full interface for all sorts of symbols, but simply use the dummy implementation if they do not do a particular font type.

So how do we handle kerning and other nesting issues? (eg. the use of one font inside the subscript of another). We could just use the convention that all moving of boxes should be handled in a lib-layout compatible way, or that at least the nucleus/sub/super members accept either unicode values or pointers to gtkboxes.

Note that the font renderer is NOT responsible for actually understanding the dom tree and converting that to glyph compositions. It is just there to make sure that the metrics and other size info stored in the font gets used to correctly draw glyphs and compose them with existing gtklayout boxes.

Structure of nodes

Each node, roughly speaking, consists of the following parts,

  1. nucleus
  2. subscript
  3. superscript
There are several types of nodes,
  1. ordinary symbol
  2. operator
  3. binary operator
  4. relation
  5. opening parenthesis
  6. closing parenthesis
  7. punctuation
  8. overline
  9. underline
  10. radical
  11. fraction

Operators and extensible symbols

(this text doesn't really belong here, but as we don't have a font module yet...)

TeX handles mathematical symbols with additional arguments (eg. integral symbols, summation symbols, roots and so on) very well. The information about where to put the additional symbols (eg. integration ranges, summation limits, root exponents and so on) is usually not available with fonts. The same holds true for extensible characters like braces ('{' and '}'), which are to be composed of several glyphs.

The first problem is first of all one of being able to figure out the so-called `slant angle'. This is the angle at which the symbols in a font are slanted and allows the program to move superscript indices to the right and subscript indices to the left. Such information is available in the TFM metric format as described in appendix G of the TeXbook. It seems that there are no other well-known font formats that provide the math metric information TeX needs (Postscript and TrueType fonts do not contain these parameters; programs using them to typeset mathematics (eg. FrameMaker) seem to have these parameters hardcoded into the program itself).

For roots, this is more complicated. In TFM metric info, the position of the root exponent is stored as...

We also need to know the sizes of characters, for super/sub scripts.

TeX distinguishes 4 font families: normal text fonts and math italic fonts have 7 paramaters, symbol fonts have 22 font parameters, while extensible fonts have 13 of them. Symbol fonts contain so many parameters because they contain operator glyphs. For these operators it is necessary to know the various distances to super and subscripts in various displya

1 slant factor (accent positioning in slanted typefaces)
2 interword distance (=\spaceskip)
3 interword stretch (=plus-part of \spaceskip)
4 interword shrink (=minus-part of \spaceskip)
5 x height = 1ex
6 M width = 1em
7 extraskip after \sfcodes larger than 2000 (=\xspaceskip)
8 .. 12 vertical shift parameters for fractions according to mathstyle
8,9,10 apply to numerator
11,12 apply to denominator
13 minimum shift upwards for exponents (\displaystyle)
14 same for roots
15 same for other cases
16 minimum vertical distance between index and baseline
17 same if an Exponent is present
18 base shift for exponents
19 base shift for indices
20 minimum size for parantheses (\displaystyle)
21 same for other mathstyles
22 used by \vcenter: position of the vertical 'symmetry line'

Where are super/sub scripts? http://www.cybercomm.nl/~bittext/