<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
<title></title>
</head>
<body bgcolor="#ffffff" text="#000000">
Jens Jorgen Mortensen wrote:
<blockquote cite="mid41C97E22.6040206@..." type="cite">Felix
Wiemann wrote:
<br>
<blockquote type="cite">However, I think that it complicates the
writing of the math role, so
<br>
may I suggest you implement a simple (yet working) prototype first?
<br>
Then you can later refactor it to use a node tree structure, moving the
<br>
math parsing from the HTML writer to the reST parser.
<br>
</blockquote>
<br>
OK, I have a working prototype. I have attached the code as a patch
against docutils-0.3.5. Have a look a test.txt to see some examples.
It works like this:
<br>
<br>
rst2html.py test.txt > test.xhtml
<br>
<br>
or
<br>
<br>
rst2latex test.txt > test.tex
<br>
<br>
I would be very happy if someone could try it out - any comments and
questions are welcome. If your favorite math equation doesn't parse
well (or not at all) then let me know.
<br>
<br>
Note that there are many missing symbols - there are currently only two
greek letters: alpha and epsilon. I haven't had time to add them all.
<br>
<br>
I will be on vacation the next 11 days, so I will probably not answer
emails before 2005!
<br>
<br>
Jens Jørgen
<br>
<pre wrap="">
<hr size="4" width="90%">
Testing MathML
--------------
Inline math: :latex-math:`\sin(x_n^2)`. And displayed math:
.. latex-math::
f(\epsilon) = \frac{1}{1 + \exp\left(\frac{\epsilon}{k_\text{B}T}\right)}
.. latex-math::
N = \frac{\text{number of apples}}{7}
.. latex-math::
\mathbf{M} = \left(\begin{matrix}a&b\\c&d\end{matrix}\right)
We have :latex-math:`|\mathbf{M}| = ad - bc`.
.. latex-math::
\int_0^1 x^n dx = \frac{1}{n + 1}
.. latex-math::
\sum_{n=1}^m n = \frac{m(m+1)}{2}
* tilde: :latex-math:`\tilde{n}`
* hat: :latex-math:`\hat{H}`
* bar: :latex-math:`\bar{v}`
Math split over Two lines:
.. latex-math::
g(\alpha) = & (1 + \alpha + \alpha^2 + \alpha^3 + \alpha^4\\
& + \alpha^5)
.. latex-math::
f(x) = \left\{
\begin{matrix}
1 - x, & x < 1 \\
0, & x > 1
\end{matrix}\right.
</pre>
<pre wrap="">
<hr size="4" width="90%">
diff -urN docutils.0.3.5/nodes.py docutils/nodes.py
--- docutils.0.3.5/nodes.py 2004-06-23 04:25:34.000000000 +0200
+++ docutils/nodes.py 2004-12-22 14:16:58.000000000 +0100
@@ -1212,6 +1212,12 @@
class generated(Inline, TextElement): pass
+class latex_math(Inline, Text):
+ tagname = '#latex-math'
+ def __init__(self, rawsource, latex):
+ Text.__init__(self, latex, rawsource)
+
+
# ========================================
# Auxiliary Classes, Functions, and Data
# ========================================
@@ -1231,7 +1237,7 @@
generated
header hint
image important info inline
- label legend line_block list_item literal literal_block
+ label latex_math legend line line_block list_item literal literal_block
note
option option_argument option_group option_list option_list_item
option_string organization
diff -urN docutils.0.3.5/parsers/rst/directives/__init__.py docutils/parsers/rst/directives/__init__.py
--- docutils.0.3.5/parsers/rst/directives/__init__.py 2004-06-23 05:44:06.000000000 +0200
+++ docutils/parsers/rst/directives/__init__.py 2004-12-22 14:17:44.000000000 +0100
@@ -126,7 +126,8 @@
'unicode': ('misc', 'unicode_directive'),
'class': ('misc', 'class_directive'),
'role': ('misc', 'role'),
- 'restructuredtext-test-directive': ('misc', 'directive_test_function'),}
+ 'restructuredtext-test-directive': ('misc', 'directive_test_function'),
+ 'latex-math': ('latex_math', 'latex_math')}
"""Mapping of directive name to (module name, function name). The directive
name is canonical & must be lowercase. Language-dependent names are defined
in the ``language`` subpackage."""
diff -urN docutils.0.3.5/parsers/rst/directives/latex_math.py docutils/parsers/rst/directives/latex_math.py
--- docutils.0.3.5/parsers/rst/directives/latex_math.py 1970-01-01 01:00:00.000000000 +0100
+++ docutils/parsers/rst/directives/latex_math.py 2004-12-22 14:18:20.000000000 +0100
@@ -0,0 +1,19 @@
+"""
+Directive for LaTeX math.
+"""
+
+__docformat__ = 'reStructuredText'
+
+
+import sys
+from docutils import nodes
+
+
+def latex_math(name, arguments, options, content, lineno,
+ content_offset, block_text, state, state_machine):
+ node = nodes.latex_math(block_text, ''.join(content))
+ return [node]
+
+latex_math.arguments = None
+latex_math.options = {}
+latex_math.content = 1
diff -urN docutils.0.3.5/parsers/rst/roles.py docutils/parsers/rst/roles.py
--- docutils.0.3.5/parsers/rst/roles.py 2004-06-16 19:21:56.000000000 +0200
+++ docutils/parsers/rst/roles.py 2004-12-22 14:33:02.000000000 +0100
@@ -287,6 +287,15 @@
register_canonical_role('rfc-reference', rfc_reference_role)
+def latex_math_role(role, rawtext, text, lineno, inliner,
+ options={}, content=[]):
+ i = rawtext.find('`')
+## node = nodes.latex_math(rawtext, text.replace('\x00','\\'))
+ node = nodes.latex_math(rawtext, rawtext[i+1:-1])
+ return [node], []
+
+register_canonical_role('latex-math', latex_math_role)
+
######################################################################
# Register roles that are currently unimplemented.
diff -urN docutils.0.3.5/writers/html4css1.py docutils/writers/html4css1.py
--- docutils.0.3.5/writers/html4css1.py 2004-07-26 19:58:01.000000000 +0200
+++ docutils/writers/html4css1.py 2004-12-22 14:20:42.000000000 +0100
@@ -28,6 +28,7 @@
Image = None
import docutils
from docutils import frontend, nodes, utils, writers, languages
+from docutils.writers.mathml import mathml
class Writer(writers.Writer):
@@ -843,6 +844,15 @@
def depart_label(self, node):
self.body.append(']</a></td><td>%s' % self.context.pop())
+ def visit_latex_math(self, node):
+ text = node.astext()
+ inline = isinstance(node.parent, nodes.TextElement)
+ mml = mathml(text, inline)
+ self.body.append(mml)
+
+ def depart_latex_math(self, node):
+ pass
+
def visit_legend(self, node):
self.body.append(self.starttag(node, 'div', CLASS='legend'))
diff -urN docutils.0.3.5/writers/latex2e.py docutils/writers/latex2e.py
--- docutils.0.3.5/writers/latex2e.py 2004-07-29 02:27:45.000000000 +0200
+++ docutils/writers/latex2e.py 2004-12-22 14:21:20.000000000 +0100
@@ -1388,6 +1388,17 @@
return
self.body.append(']')
+ def visit_latex_math(self, node):
+ inline = isinstance(node.parent, nodes.TextElement)
+ if inline:
+ self.body.append('$%s$' % node.astext())
+ else:
+ self.body.append('\\begin{eqnarray} %s \\end{eqnarray}\n' % \
+ node.astext())
+
+ def depart_latex_math(self, node):
+ pass
+
# elements generated by the framework e.g. section numbers.
def visit_generated(self, node):
pass
diff -urN docutils.0.3.5/writers/mathml.py docutils/writers/mathml.py
--- docutils.0.3.5/writers/mathml.py 1970-01-01 01:00:00.000000000 +0100
+++ docutils/writers/mathml.py 2004-12-22 14:29:17.000000000 +0100
@@ -0,0 +1,346 @@
+class math:
+ nchildren = 1000000
+ def __init__(self, children=None):
+ self.children = []
+ if children is not None:
+ if type(children) is list:
+ for child in children:
+ self.append(child)
+ else:
+ self.append(children)
+
+ def __repr__(self):
+ if hasattr(self, 'children'):
+ return self.__class__.__name__ + '(%s)' % \
+ ','.join([repr(child) for child in self.children])
+ else:
+ return self.__class__.__name__
+
+ def full(self):
+ return len(self.children) >= self.nchildren
+
+ def append(self, child):
+ assert not self.full()
+ self.children.append(child)
+ child.parent = self
+ node = self
+ while node.full():
+ node = node.parent
+ return node
+
+ def delete_child(self):
+ child = self.children[-1]
+ del self.children[-1]
+ return child
+
+ def close(self):
+ parent = self.parent
+ while parent.full():
+ parent = parent.parent
+ return parent
+
+ def xml(self):
+ return self.xml_start() + self.xml_body() + self.xml_end()
+
+ def xml_start(self):
+ return ['<math:%s>' % self.__class__.__name__]
+
+ def xml_end(self):
+ return ['</math:%s>' % self.__class__.__name__]
+
+ def xml_body(self):
+ xml = []
+ for child in self.children:
+ xml.extend(child.xml())
+ return xml
+
+class mrow(math): pass
+class mtable(math): pass
+class mtr(mrow): pass
+class mtd(mrow): pass
+
+class mx(math):
+ nchildren = 0
+ def __init__(self, data):
+ self.data = data
+
+ def xml_body(self):
+ return [self.data]
+
+class mo(mx):
+ translation = {'<': '&lt;', '>': '&gt;'}
+ def xml_body(self):
+ return [self.translation.get(self.data, self.data)]
+
+class mi(mx): pass
+class mn(mx): pass
+
+class msub(math):
+ nchildren = 2
+
+class msup(math):
+ nchildren = 2
+
+class msqrt(math):
+ nchildren = 1
+
+class mroot(math):
+ nchildren = 2
+
+class mfrac(math):
+ nchildren = 2
+
+class msubsup(math):
+ nchildren = 3
+ def __init__(self, children=None, reversed=False):
+ self.reversed = reversed
+ math.__init__(self, children)
+
+ def xml(self):
+ if self.reversed:
+## self.children[1:3] = self.children[2:0:-1]
+ self.children[1:3] = [self.children[2], self.children[1]]
+ self.reversed = False
+ return math.xml(self)
+
+class mfenced(math):
+ translation = {'\\{': '{', '\\langle': u'\u2329',
+ '\\}': '}', '\\rangle': u'\u232A',
+ '.': ''}
+ def __init__(self, par):
+ self.openpar = par
+ math.__init__(self)
+
+ def xml_start(self):
+ open = self.translation.get(self.openpar, self.openpar)
+ close = self.translation.get(self.closepar, self.closepar)
+ return ['<math:mfenced math:open="%s" math:close="%s">' % \
+ (open, close)]
+
+class mspace(math):
+ nchildren = 0
+
+class mstyle(math):
+ def __init__(self, children=None, nchildren=None, **kwargs):
+ if nchildren is not None:
+ self.nchildren = nchildren
+ math.__init__(self, children)
+ self.attrs = kwargs
+
+ def xml_start(self):
+ return ['<math:mstyle '] + ['math:%s="%s"' % item
+ for item in self.attrs.items()] + ['>']
+
+class mover(math):
+ nchildren = 2
+ reversed = True
+ def xml(self):
+ if self.reversed:
+ self.children.reverse()
+ self.reversed = False
+ return math.xml(self)
+
+class mtext(math):
+ nchildren = 0
+ def __init__(self, text):
+ self.text = text
+
+ def xml_body(self):
+ return [self.text]
+
+
+escaped = {'{': 'lbrace',
+ '}': 'rbrace'}
+
+over = {'tilde': '~',
+ 'hat': '^',
+ 'bar': '_'}
+
+special = {'sum': u'\u03A3',
+ 'int': u'\u222B',
+ 'times': u'\u00D7',
+ 'alpha': u'\u03B1',
+ 'epsilon': u'\u03B5',
+ 'lbrace': u'\u007B',
+ 'rbrace': u'\u007D',
+ 'langle': u'\u2329',
+ 'rangle': u'\u232A'}
+
+functions = ['sin', 'exp', 'cos']
+
+def parse_latex_math(string, inline=True):
+ string = ' '.join(string.split())
+
+ if inline:
+ node = mrow()
+ tree = node
+ else:
+ node = mtd()
+ tree = mstyle(mtable(mtr(node)), displaystyle='true')
+
+ while len(string) > 0:
+ n = len(string)
+ c = string[0]
+ skip = 1
+ if n > 1:
+ c2 = string[1]
+ else:
+ c2 = ''
+## print n, string, c, c2, node.__class__.__name__
+ if c == ' ':
+ pass
+ elif c == '\\':
+ if c2 in escaped:
+ node = node.append(mo(escaped[c2]))
+ skip = 2
+ elif c2 == ' ':
+ node = node.append(mspace())
+ skip = 2
+ elif c2.isalpha():
+ i = 2
+ while i < n and string[i].isalpha():
+ i += 1
+ name = string[1:i]
+ node, skip = handle_keyword(name, node, string[i:])
+ skip += i
+ elif c2 == '\\':
+ entry = mtd()
+ row = mtr(entry)
+ node.close().close().append(row)
+ node = entry
+ skip = 2
+ else:
+ raise SyntaxError
+ elif c.isalpha():
+ node = node.append(mi(c))
+ elif c.isdigit():
+ node = node.append(mn(c))
+ elif c in '+-/()[]|=<>,.':
+ node = node.append(mo(c))
+ elif c == '_':
+ child = node.delete_child()
+ if isinstance(child, msup):
+ sub = msubsup(child.children[0:2], reversed=True)
+ else:
+ sub = msub(child)
+ node.append(sub)
+ node = sub
+ elif c == '^':
+ child = node.delete_child()
+ if isinstance(child, msub):
+ sup = msubsup(child.children[0:2])
+ else:
+ sup = msup(child)
+ node.append(sup)
+ node = sup
+ elif c == '{':
+ row = mrow()
+ node.append(row)
+ node = row
+ elif c == '}':
+ node = node.close()
+ elif c == '&':
+ entry = mtd()
+ node.close().append(entry)
+ node = entry
+ else:
+ raise SyntaxError
+ string = string[skip:]
+ return tree
+
+
+def handle_keyword(name, node, string):
+ skip = 0
+ if name == 'begin':
+ assert string.startswith('{matrix}')
+ skip = 8
+ entry = mtd()
+ row = mtr(entry)
+ table = mtable(row)
+ node.append(table)
+ node = entry
+ elif name == 'end':
+ assert string.startswith('{matrix}')
+ skip = 8
+ node = node.close().close().close()
+ elif name == 'text':
+ assert string[0] == '{'
+ i = string.index('}')
+ node = node.append(mtext(string[1:i]))
+ skip = i + 1
+ elif name == 'sqrt':
+ sqrt = msqrt()
+ node.append(sqrt)
+ node = sqrt
+ elif name == 'frac':
+ frac = mfrac()
+ node.append(frac)
+ node = frac
+ elif name == 'left':
+ if string[0] == ' ':
+ string = string[1:]
+ skip = 1
+ for par in ['(', '[', '|', '\\{', '\\langle', '.']:
+ if string.startswith(par):
+ break
+ else:
+ raise SyntaxError
+ fenced = mfenced(par)
+ node.append(fenced)
+ node = fenced
+ skip += len(par)
+ elif name == 'right':
+ if string[0] == ' ':
+ string = string[1:]
+ skip = 1
+ for par in [')', ']', '|', '\\}', '\\rangle', '.']:
+ if string.startswith(par):
+ break
+ else:
+ raise SyntaxError
+ node.closepar = par
+ node = node.close()
+ skip += len(par)
+ elif name == 'mathbf':
+ style = mstyle(nchildren=1, fontweight='bold')
+ node.append(style)
+ node = style
+ else:
+ code = special.get(name)
+ if code is not None:
+ node = node.append(mi(code))
+ else:
+ if name in functions:
+ node = node.append(mo(name))
+ else:
+ chr = over.get(name)
+ if chr is not None:
+ ov = mover(mo(chr))
+ node.append(ov)
+ node = ov
+ else:
+ raise SyntaxError
+
+ return node, skip
+
+
+def mathml(string, inline):
+ tree = parse_latex_math(string, inline)
+## print repr(tree)
+ xml = ''.join(tree.xml())
+ xml = """<math:math xmlns:math=<a class="moz-txt-link-rfc2396E" href="http://www.w3.org/1998/Math/MathML">"http://www.w3.org/1998/Math/MathML"</a>>
+ <math:semantics>
+ %s
+ </math:semantics>
+ </math:math>
+ """ % xml
+ if inline:
+ return xml
+ return xml + '<br/>\n'
+
+
+if __name__ == '__main__':
+ import sys
+ tree = parse_latex_math(sys.argv[1], 1)
+ print repr(tree)
+ print ''.join(tree.xml())
</pre>
</blockquote>
<big>This seems a long way from what Alan Isaac proposed:
<a class="moz-txt-link-freetext" href="http://www1.chapman.edu/~jipsen/mathml/asciimath.html">http://www1.chapman.edu/~jipsen/mathml/asciimath.html</a><br>
<br>
The beauty of that proposal is that the markup intrudes very little
into the maths. It is largely readable. <br>
<br>
See excerpt below (with apologies for the HTML):<br>
</big><br>
<h4>Here are a few more examples:
</h4>
<table id="examples" border="5" cellpadding="10">
<tbody>
<tr>
<th>Type this</th>
<th>See that</th>
<th>Comment</th>
</tr>
<tr>
<td>`x^2+y_1+z_12^34`</td>
<td><math><mstyle displaystyle="true" mathcolor="Red"><msup><mi>x</mi><mn>2</mn></msup><mo>+</mo><msub><mi>y</mi><mn>1</mn></msub><mo>+</mo><mrow><msubsup><mi>z</mi><mn>12</mn><mn>34</mn></msubsup></mrow><mo></mo></mstyle></math></td>
<td>subscripts as in TeX, but numbers are treated as a unit</td>
</tr>
<tr>
<td>`sin^-1(x)`</td>
<td><math><mstyle displaystyle="true" mathcolor="Red"><msup><mo>sin</mo><mn>-1</mn></msup><mrow><mo>(</mo><mi>x</mi><mo>)</mo></mrow></mstyle></math></td>
<td>function names are treated as constants</td>
</tr>
<tr>
<td>`d/dxf(x)=lim_(h->0)(f(x+h)-f(x))/h`</td>
<td><math><mstyle displaystyle="true" mathcolor="Red"><mfrac><mi>d</mi><mrow><mi>d</mi><mi>x</mi></mrow></mfrac><mi>f</mi><mrow><mo>(</mo><mi>x</mi><mo>)</mo></mrow><mo>=</mo><munder><mo>lim</mo><mrow><mi>h</mi><mo>→</mo><mn>0</mn></mrow></munder><mfrac><mrow><mi>f</mi><mrow><mo>(</mo><mi>x</mi><mo>+</mo><mi>h</mi><mo>)</mo></mrow><mo>-</mo><mi>f</mi><mrow><mo>(</mo><mi>x</mi><mo>)</mo></mrow></mrow><mi>h</mi></mfrac><mo></mo></mstyle></math></td>
<td>complex subscripts are bracketed, displayed under lim</td>
</tr>
<tr>
<td>$\frac{d}{dx}f(x)=\lim_{h\to 0}\frac{f(x+h)-f(x)}{h}$</td>
<td><math><mstyle displaystyle="true" mathcolor="Red"><mfrac><mrow><mi>d</mi></mrow><mrow><mrow><mi>d</mi><mi>x</mi></mrow></mrow></mfrac><mi>f</mi><mrow><mo>(</mo><mi>x</mi><mo>)</mo></mrow><mo>=</mo><munder><mo>lim</mo><mrow><mi>h</mi><mo>→</mo><mn>0</mn></mrow></munder><mfrac><mrow><mi>f</mi><mrow><mo>(</mo><mi>x</mi><mo>+</mo><mi>h</mi><mo>)</mo></mrow><mo>-</mo><mi>f</mi><mrow><mo>(</mo><mi>x</mi><mo>)</mo></mrow></mrow><mrow><mi>h</mi></mrow></mfrac></mstyle></math></td>
<td>standard LaTeX notation is an alternative</td>
</tr>
<tr>
<td>`f(x)=sum_(n=0)^oo(f^((n))(a))/(n!)(x-a)^n`</td>
<td><math><mstyle displaystyle="true" mathcolor="Red"><mi>f</mi><mrow><mo>(</mo><mi>x</mi><mo>)</mo></mrow><mo>=</mo><mrow><munderover><mo>∑</mo><mrow><mi>n</mi><mo>=</mo><mn>0</mn></mrow><mo>∞</mo></munderover></mrow><mfrac><mrow><msup><mi>f</mi><mrow><mrow><mo>(</mo><mi>n</mi><mo>)</mo></mrow></mrow></msup><mrow><mo>(</mo><mi>a</mi><mo>)</mo></mrow></mrow><mrow><mi>n</mi><mo>!</mo></mrow></mfrac><msup><mrow><mo>(</mo><mi>x</mi><mo>-</mo><mi>a</mi><mo>)</mo></mrow><mi>n</mi></msup><mo></mo></mstyle></math></td>
<td>f^((n))(a) must be bracketed, else the numerator is only <math><mstyle
displaystyle="true" mathcolor="Red"><mi>a</mi></mstyle></math></td>
</tr>
<tr>
<td>$f(x)=\sum_{n=0}^\infty\frac{f^{(n)}(a)}{n!}(x-a)^n$</td>
<td><math><mstyle displaystyle="true" mathcolor="Red"><mi>f</mi><mrow><mo>(</mo><mi>x</mi><mo>)</mo></mrow><mo>=</mo><mrow><munderover><mo>∑</mo><mrow><mi>n</mi><mo>=</mo><mn>0</mn></mrow><mo>∞</mo></munderover></mrow><mfrac><mrow><msup><mi>f</mi><mrow><mrow><mo>(</mo><mi>n</mi><mo>)</mo></mrow></mrow></msup><mrow><mo>(</mo><mi>a</mi><mo>)</mo></mrow></mrow><mrow><mi>n</mi><mo>!</mo></mrow></mfrac><msup><mrow><mo>(</mo><mi>x</mi><mo>-</mo><mi>a</mi><mo>)</mo></mrow><mi>n</mi></msup><mo></mo></mstyle></math></td>
<td>standard LaTeX produces the same result</td>
</tr>
<tr>
<td>`int_0^1f(x)dx`</td>
<td><math><mstyle displaystyle="true" mathcolor="Red"><mrow><msubsup><mo>∫</mo><mn>0</mn><mn>1</mn></msubsup></mrow><mi>f</mi><mrow><mo>(</mo><mi>x</mi><mo>)</mo></mrow><mrow><mi>d</mi><mi>x</mi></mrow></mstyle></math></td>
<td>subscripts must come before superscripts</td>
</tr>
<tr>
<td>`[[a,b],[c,d]]((n),(k))`</td>
<td><math><mstyle displaystyle="true" mathcolor="Red"><mrow><mo>[</mo><mtable><mtr><mtd><mi>a</mi></mtd><mtd><mi>b</mi></mtd></mtr><mtr><mtd><mi>c</mi></mtd><mtd><mi>d</mi></mtd></mtr></mtable><mo>]</mo></mrow><mrow><mo>(</mo><mtable><mtr><mtd><mi>n</mi></mtd></mtr><mtr><mtd><mi>k</mi></mtd></mtr></mtable><mo>)</mo></mrow></mstyle></math></td>
<td>matrices and column vectors are simple to type</td>
</tr>
<tr>
<td>`x/x={(1,if x!=0),(text{undefined},if x=0):}`</td>
<td><math><mstyle displaystyle="true" mathcolor="Red"><mfrac><mi>x</mi><mi>x</mi></mfrac><mo>=</mo><mrow><mo>{</mo><mtable
columnalign="left"><mtr><mtd columnalign="left"><mn>1</mn></mtd><mtd
columnalign="left"><mrow><mspace width="1ex"></mspace><mo>if</mo><mspace
width="1ex"></mspace></mrow><mi>x</mi><mo>≠</mo><mn>0</mn></mtd></mtr><mtr><mtd
columnalign="left"><mrow><mtext>undefined</mtext></mrow></mtd><mtd
columnalign="left"><mrow><mspace width="1ex"></mspace><mo>if</mo><mspace
width="1ex"></mspace></mrow><mi>x</mi><mo>=</mo><mn>0</mn></mtd></mtr></mtable></mrow></mstyle></math></td>
<td>piecewise defined function are based on matrix notation</td>
</tr>
<tr>
<td>`a//b`</td>
<td><math><mstyle displaystyle="true" mathcolor="Red"><mi>a</mi><mo>/</mo><mi>b</mi></mstyle></math></td>
<td>use // for inline fractions</td>
</tr>
<tr>
<td>`(a/b)/(c/d)`</td>
<td><math><mstyle displaystyle="true" mathcolor="Red"><mfrac><mrow><mfrac><mi>a</mi><mi>b</mi></mfrac></mrow><mrow><mfrac><mi>c</mi><mi>d</mi></mfrac></mrow></mfrac><mo></mo></mstyle></math></td>
<td>with brackets, multiple fraction work as expected</td>
</tr>
<tr>
<td>`a/b/c/d`</td>
<td><math><mstyle displaystyle="true" mathcolor="Red"><mfrac><mi>a</mi><mi>b</mi></mfrac><mo>/</mo><mfrac><mi>c</mi><mi>d</mi></mfrac><mo></mo></mstyle></math></td>
<td>without brackets the parser chooses this particular expression</td>
</tr>
<tr>
<td>`((a*b))/c`</td>
<td><math><mstyle displaystyle="true" mathcolor="Red"><mfrac><mrow><mrow><mo>(</mo><mi>a</mi><mo>⋅</mo><mi>b</mi><mo>)</mo></mrow></mrow><mi>c</mi></mfrac><mo></mo></mstyle></math></td>
<td>only one level of brackets is removed; * gives standard
product</td>
</tr>
<tr>
<td>`sqrtsqrtroot3x`</td>
<td><math><mstyle displaystyle="true" mathcolor="Red"><msqrt><msqrt><mroot><mi>x</mi><mn>3</mn></mroot></msqrt></msqrt></mstyle></math></td>
<td>spaces are optional, only serve to split strings that should
not match</td>
</tr>
<tr>
<td>`(:a,b:) and {:(x,y),(u,v):}`</td>
<td><math><mstyle displaystyle="true" mathcolor="Red"><mrow><mo>〈</mo><mi>a</mi><mo>,</mo><mi>b</mi><mo>〉</mo></mrow><mrow><mspace
width="1ex"></mspace><mtext>and</mtext><mspace width="1ex"></mspace></mrow><mrow><mtable
columnalign="left"><mtr><mtd columnalign="left"><mi>x</mi></mtd><mtd
columnalign="left"><mi>y</mi></mtd></mtr><mtr><mtd columnalign="left"><mi>u</mi></mtd><mtd
columnalign="left"><mi>v</mi></mtd></mtr></mtable></mrow></mstyle></math></td>
<td>angle brackets and invisible brackets</td>
</tr>
<tr>
<td>`(a,b]={x in RR : a < x <= b}`</td>
<td><math><mstyle displaystyle="true" mathcolor="Red"><mrow><mo>(</mo><mi>a</mi><mo>,</mo><mi>b</mi><mo>]</mo></mrow><mo>=</mo><mrow><mo>{</mo><mi>x</mi><mo>∈</mo><mo>ℝ</mo><mo>:</mo><mi>a</mi><mo><</mo><mi>x</mi><mo>≤</mo><mi>b</mi><mo>}</mo></mrow></mstyle></math></td>
<td>grouping brackets don't have to match</td>
</tr>
<tr>
<td>`abc-123.45^-1.1`</td>
<td><math><mstyle displaystyle="true" mathcolor="Red"><mi>a</mi><mi>b</mi><mi>c</mi><msup><mn>-123.45</mn><mn>-1.1</mn></msup><mo></mo></mstyle></math></td>
<td>non-tokens are split into single characters,<br>
but decimal numbers are parsed with possible sign</td>
</tr>
<tr>
<td>`hat(ab) bar(xy) ulA vec v dotx ddot y`</td>
<td><math><mstyle displaystyle="true" mathcolor="Red"><mover><mrow><mi>a</mi><mi>b</mi></mrow><mo>^</mo></mover><mover><mrow><mi>x</mi><mi>y</mi></mrow><mo>¯</mo></mover><munder><mi>A</mi><mo>̲</mo></munder><mover><mi>v</mi><mo>→</mo></mover><mover><mi>x</mi><mo>.</mo></mover><mover><mi>y</mi><mo>..</mo></mover></mstyle></math></td>
<td>accents can be used on any expression (work well in IE)</td>
</tr>
<tr>
<td>`bb{AB3}.bbb(AB].cc(AB).fr{AB}.tt[AB].sf(AB)`</td>
<td><math><mstyle displaystyle="true" mathcolor="Red"><mstyle
fontweight="bold"><mrow><mi>A</mi><mi>B</mi><mn>3</mn></mrow></mstyle><mo>.</mo><mstyle
mathvariant="double-struck"><mrow></mrow></mstyle><mo>.</mo><mstyle
mathvariant="script"><mrow>ℬ</mrow></mstyle><mo>.</mo><mstyle
mathvariant="fraktur"><mrow></mrow></mstyle><mo>.</mo><mstyle
fontfamily="monospace"><mrow><mi>A</mi><mi>B</mi></mrow></mstyle><mo>.</mo><mstyle
fontfamily="sans-serif"><mrow><mi>A</mi><mi>B</mi></mrow></mstyle></mstyle></math></td>
<td>font commands; can use any brackets around argument</td>
</tr>
<tr>
<td>`stackrel"def"= or \stackrel{\Delta}{=}" "("or ":=)`</td>
<td><math><mstyle displaystyle="true" mathcolor="Red"><mover><mo>=</mo><mrow><mtext>def</mtext></mrow></mover><mrow><mspace
width="1ex"></mspace><mtext>or</mtext><mspace width="1ex"></mspace></mrow><mover><mrow><mo>=</mo></mrow><mrow><mo>Δ</mo></mrow></mover><mrow><mspace
width="1ex"></mspace><mtext></mtext><mspace width="1ex"></mspace></mrow><mrow><mo>(</mo><mrow><mtext>or</mtext><mspace
width="1ex"></mspace></mrow><mo>:=</mo><mo>)</mo></mrow></mstyle></math></td>
<td>symbols can be stacked</td>
</tr>
<tr>
<td>`{::}_(\ 92)^238U`</td>
<td><math><mstyle displaystyle="true" mathcolor="Red"><mrow><msubsup><mrow></mrow><mrow><mo> </mo><mn>92</mn></mrow><mn>238</mn></msubsup></mrow><mi>U</mi></mstyle></math></td>
<td>prescripts simulated by subsuperscripts</td>
</tr>
</tbody>
</table>
<big><br>
The problem with the test.txt is that the math is lost in the markup.<br>
<br>
I am not advocating that ASCII be adopted as a standard for reST but
that it would be very helpful, for those who are not familiar with the
detail of Latex and have no wish to become "texnicians", to have a
means of integrating such a script into reST.<br>
<br>
Colin W</big>.<br>
</body>
</html>
|