Blog de Frédéric - Tag - mathmlFrédéric Wang's Blog, about mathematics and computer science / Blog de Frédéric Wang, sur les mathématiques et l'informatique.2014-03-30T15:35:28+02:00Frédéric Wangurn:md5:856637f86f94ed5243b6f6f713360bdaDotclearTeXZilla 0.9.4 Releasedurn:md5:537ff152e61d2f4fa291da2a05fa41ef2014-02-25T21:20:00+01:002014-03-11T11:32:07+01:00fredwarabicbisonlatexmathmlmathzillamozillaunicode <p><strong>update 2014/03/11: TeXZilla is now available as an <a href="https://www.npmjs.org/package/texzilla">npm module</a>.</strong></p>
<h2>Introduction</h2>
<p>For the past two months, the Mozilla MathML team has been working on
<a href="http://fred-wang.github.io/TeXZilla/">TeXZilla</a>, yet another
LaTeX-to-MathML converter. The idea was to rely on
<a href="http://golem.ph.utexas.edu/~distler/blog/itex2MML.html">itex2MML</a> (which dates back from the beginning of the Mozilla MathML project) to
create a LaTeX parser such that:
</p>
<ul>
<li>It is compatible with the
<a href="http://golem.ph.utexas.edu/~distler/blog/itex2MMLcommands.html">itex2MML syntax</a> and is similarly generated from a LALR(1) grammar
(the goal is only to support a restricted set of core LaTeX commands for
mathematics, for a more complete converter of LaTeX documents see
<a href="https://github.com/brucemiller/LaTeXML">LaTeXML</a>).
</li>
<li>It is available as a standalone Javascript module
usable in all the Mozilla Web applications and add-ons (of course,
it will work in non-Mozilla products too).</li>
<li>It accepts any Unicode characters and supports right-to-left
mathematical notation
(these are important for the world-wide aspect of the Mozilla
community).
</li>
</ul>
<p>The parser is generated with the help of
<a href="http://zaach.github.io/jison/">Jison</a> and relies on a
grammar based on the one of itex2MML and on the
<code>unicode.xml</code> file of the
<a href="http://www.w3.org/TR/xml-entity-names/">XML Entity Definitions
for Characters specification</a>. As suggested by the version number,
this is still
<a href="https://github.com/fred-wang/TeXZilla/issues?state=open">in development</a>. However, we have made enough progress to
present interesting features here and get more
users and developers involved.
</p>
<h2>Quick Examples</h2>
<p><code>\frac{x^2}{a^2} + \frac{y^2}{b^2} = 1</code></p>
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mfrac><msup><mi>x</mi><mn>2</mn></msup><msup><mi>a</mi><mn>2</mn></msup></mfrac><mo>+</mo><mfrac><msup><mi>y</mi><mn>2</mn></msup><msup><mi>b</mi><mn>2</mn></msup></mfrac><mo>=</mo><mn>1</mn></mrow><annotation encoding="TeX">\frac{x^2}{a^2} + \frac{y^2}{b^2} = 1</annotation></semantics></math>
<p><code>∑_{n=1}^{+∞} \frac{1}{n^2} = \frac{π^2}{6}</code></p>
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><munderover><mo>∑</mo><mrow><mi>n</mi><mo>=</mo><mn>1</mn></mrow><mrow><mo>+</mo><mn>∞</mn></mrow></munderover><mfrac><mn>1</mn><msup><mi>n</mi><mn>2</mn></msup></mfrac><mo>=</mo><mfrac><msup><mi>π</mi><mn>2</mn></msup><mn>6</mn></mfrac></mrow><annotation encoding="TeX">∑_{n=1}^{+∞} \frac{1}{n^2} = \frac{π^2}{6}</annotation></semantics></math>
<p><code>س = \frac{-ب\pm\sqrt{ب^٢-٤اج}}{٢ا}</code></p>
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><mrow><mi>س</mi><mo>=</mo><mfrac><mrow><mo>-</mo><mi>ب</mi><mo>±</mo><msqrt><mrow><msup><mi>ب</mi><mn>٢</mn></msup><mo>-</mo><mn>٤</mn><mi>ا</mi><mi>ج</mi></mrow></msqrt></mrow><mrow><mn>٢</mn><mi>ا</mi></mrow></mfrac></mrow><annotation encoding="TeX">س = \frac{-ب\pm\sqrt{ب^٢-٤اج}}{٢ا}</annotation></semantics></math>
<h2>Live Demo / FirefoxOS Web app</h2>
<p>A <a href="http://fred-wang.github.io/TeXZilla/">live demo</a> is
available to let you test the LaTeX-to-MathML converter with various
options and examples. For people willing to use the converter on their
mobiles a <a href="http://r-gaia-cs.github.io/TeXZilla-webapp/">FirefoxOS Web app</a> is also available.</p>
<h2>Using TeXZilla in a CommonJS program or Web page</h2>
<p>TeXZilla is made of a single <code>TeXZilla.js</code> file with
a <a href="https://github.com/fred-wang/TeXZilla/wiki/Public-API">public
API</a> to convert LaTeX to MathML or extract the TeX source from a
MathML element. The converter accepts some options like
inline/display mode or RTL/LTR direction of mathematics.</p>
<p>You can load it the standard way in any Javascript
program and obtain a <code>TeXZilla</code> object that exposes the public
API.
For example in a commonJS program, to convert a TeX source into a MathML
source:</p>
<pre>
var TeXZilla = require("./TeXZilla");
console.log(TeXZilla.toMathMLString("\\sqrt{\\frac{x}{2}+y}"));
</pre>
<p>or in a Web Page, to convert a TeX source into a MathML DOM element:
<pre>
<script type="text/javascript" src="http://www.maths-informatique-jeux.com/blog/frederic/?post/2014/02/25/TeXZilla.js"></script>
...
var MathMLElement = TeXZilla.toMathML("\\sqrt{\\frac{x}{2}+y}");
</pre>
<h2>Using TeXZilla in Mozilla Add-ons</h2>
<p>One of the goal of TeXZilla is to be integrated in Mozilla add-ons,
allowing people to write cool math applications (in particular, we would
like to have an <a href="https://github.com/fred-wang/Mathzilla/issues/9">add-on for Thunderbird</a>).
A simple <a href="https://addons.mozilla.org/en-US/firefox/addon/texzilla/">Firefox add-on</a> has been written and passed the AMO review, which means
that you can safely include the <code>TeXZilla.js</code> script in your
own add-ons.
</p>
<p>TeXZilla can be used as an
<a href="https://github.com/mozilla/addon-sdk/wiki/Community-developed-modules">addon-sdk module</a>. However, if you intend to use features
requiring a DOMParser instance (for example <code>toMathML</code>),
you need to initialize the DOM explicitly:
</p>
<pre>
var {Cc, Ci} = require("chrome");
TeXZilla.setDOMParser(Cc["@mozilla.org/xmlextras/domparser;1"].
createInstance(Ci.nsIDOMParser));
</pre>
<p>More generally, for traditional Mozilla add-ons, you can do</p>
<pre>
TeXZilla.setDOMParser(Components.
classes["@mozilla.org/xmlextras/domparser;1"].
createInstance(Components.interfaces.nsIDOMParser));
</pre>
<h2>Using TeXZilla from the command line</h2>
<p>TeXZilla has a basic command line interface. However, since
<a href="http://wiki.commonjs.org/wiki/CommonJS">CommonJS</a> is still being
standardized, this may work inconsistently between commonjs interpreters.
We have tested it on <a href="http://slimerjs.org/">slimerjs</a> (which
uses Gecko),
<a href="http://phantomjs.org/">phantomjs</a> and
<a href="http://nodejs.org/">nodejs</a>. For example you can do
</p>
<pre> $ slimerjs TeXZilla.js parser "a^2+b^2=c^2" true
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><semantics><...
</pre>
<p>or launch a Web service (see next section). We plan to implement a stream
filter too so that it can behave the same as itex2MML: looking the LaTeX
fragments from a text document and converting them into MathML.</p>
<h2>Using TeXZilla as a Web Server</h2>
<p>TeXZilla can be used as a Web Server that receives POST and GET HTTP requests
with the LaTeX input and sends JSON replies with the MathML output. The typical
use case is for people willing to perform some server-side LaTeX-to-MathML conversion.</p>
<p>For instance, to start the TeXZilla Webserver on port 7777:</p>
<pre>
$ nodejs TeXZilla.js webserver 7777
Web server started on http://localhost:7777
</pre>
<p>Then you can sent a POST request:</p>
<pre> $ curl -H "Content-Type: application/json" -X POST -d '{"tex":"x+y","display":"true"}' http://localhost:7777
{"tex":"x+y","mathml":"<math xmlns=\"http://www.w3.org/1998/Math/MathML\"...
</pre>
<p>or a GET request:</p>
<pre> $ curl "http://localhost:7777/?tex=x+y&rtl=true"
{"tex":"x+y","mathml":"<math xmlns=\"http://www.w3.org/1998/Math/MathML\"...
</pre>
<p>Note that <a href="https://github.com/fred-wang/TeXZilla/wiki/Advanced-Usages#wiki-parsing-tex-expressions-in-your-web-page">client-side</a> conversion is trivial using the public API, but see the next section.</p>
<h2>Web Components Custom Element <x-tex></h2>
<p>We used the <a href="http://www.x-tags.org/">X-Tag</a> library
to implement a simple Web Components Custom Element
<a href="https://github.com/fred-wang/x-tex"><x-tex></a>. The idea is to
have a container for LaTeX expressions like</p>
<pre> <x-tex dir="rtl">س = \frac{-ب\pm\sqrt{ب^٢-٤اج}}{٢ا}</x-tex></pre>
<p>that will be converted into MathML by TeXZilla and displayed in your
browser:
<math dir="rtl" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>س</mi><mo>=</mo><mfrac><mrow><mo>-</mo><mi>ب</mi><mo>±</mo><msqrt><mrow><msup><mi>ب</mi><mn>٢</mn></msup><mo>-</mo><mn>٤</mn><mi>ا</mi><mi>ج</mi></mrow></msqrt></mrow><mrow><mn>٢</mn><mi>ا</mi></mrow></mfrac></mrow><annotation encoding="TeX">س = \frac{-ب\pm\sqrt{ب^٢-٤اج}}{٢ا}</annotation></semantics></math>. You can
set the display/dir attributes on that <code><x-tex></code> element
and they will be applied to the <code><math></code> element. Instances of
<code><x-tex></code> elements also have a <code>source</code> property that
you can use to retrieve or set the LaTeX source. Of course, the MathML output
will automatically be updated when dynamic changes occur. You can
try <a href="http://fred-wang.github.io/x-tex/demo/">this online demo</a>.</p>
<h2>CKEditor Plugins / Integration in MDN</h2>
<p>Finally, we created a first version of a
<a href="http://ckeditor.com/addon/texzilla">TeXZilla CKEditor plugin</a>. An online demo is
<a href="http://www.ime.unicamp.br/~ra092767/ck4/plugins/texzilla/samples/index.html">available here</a>.
We already sent a <a href="https://github.com/mozilla/kuma/pull/2038">pull request to Kuma</a> and we hope it will soon enable users to put mathematical <a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Basic_Transformations#Complex_transformations_with_matrix%28%29">mathematical formulas in MDN articles</a> without having to paste the MathML into the source
code view. It could be enhanced later with a
<a href="https://github.com/r-gaia-cs/CKEditor-TeXZilla/issues/6">more advanced UI</a>.
</p>New MathML Firefox add-ons on AMOurn:md5:a826b3f19e0974de4a033d453c5298102014-01-29T13:07:00+01:002014-01-29T14:18:10+01:00fredwlatexlatexmlmathmlmathzillamediawikimozillawikipediaxpcom <p>While the patches for MathML integration in MediaWiki are
<a href="https://gerrit.wikimedia.org/r/#/projects/mediawiki/extensions/Math,dashboards/default">progressively being reviewed and merged</a> and
while we are working on the
<a href="http://www.maths-informatique-jeux.com/ulule/mathml_torture_test/">support for Open Type fonts with a MATH table</a> in Gecko, I finally
found time to check the progress in Mozilla's
<a href="https://developer.mozilla.org/en-US/Add-ons/SDK">add-on
SDK</a>. In particular, since the last time I tried (some years ago)
they have introduced a cleaner interface for content scripts as well
as the possibility to use XPCOM for missing features.
Hence I have been able to update some of my experimental MathML add-ons.
I have submitted two new add-ons to Mozilla's AMO that I hope
could be useful to some people:</p>
<ul>
<li><a href="https://addons.mozilla.org/en-US/firefox/addon/mathjax-native-mathml/">MathJax Native MathML</a>, an add-on to <strong>force MathJax to
switch to Gecko's MathML support</strong>
without having to use the MathJax menu to change the output mode
and works even on Websites where that menu is disabled.
This also removes MathJax's automatic rescaling and inline-block
<code>span</code> that are currently causing random rendering bugs
with Gecko's native MathML (and will confuse possible future
line-breaking support anyway).
<div style="width: 600px; margin-left: auto; margin-right: auto;">
<img src="https://addons.cdn.mozilla.net/img/uploads/previews/full/123/123814.png?modified=1390414386" width="600" alt="MathJax Native MathML"/>
</div>
</li>
<li>
<a href="https://addons.mozilla.org/en-US/firefox/addon/mathml-copy/">MathML Copy</a> (at the moment only partially reviewed by the AMO team), an
add-on to <strong>copy MathML and TeX into the clipboard</strong>.
For MathML, two flavors are copied: the source as plain text
(to paste in your favorite text editor)
and the MathML as HTML
(to paste in Thunderbird, MDN, any Gecko-based
HTML editor etc). Copying TeX
is only possible when it is provided via the
<a href="https://developer.mozilla.org/en-US/docs/Web/MathML/Element/semantics">standard MathML
annotation method</a>, which is the case in e.g.
<a href="http://dlmf.nist.gov/LaTeXML/">LaTeXML</a> and
<a href="http://golem.ph.utexas.edu/wiki/instiki/show/Sandbox">Instiki</a>
documents as well as in <a href="https://gerrit.wikimedia.org/r/#/c/109486/">Wikipedia in the future</a>.
<div style="width: 600px; margin-left: auto; margin-right: auto;">
<img src="https://addons.cdn.mozilla.net/img/uploads/previews/full/124/124088.png?modified=1390660049" width="600" alt="MathML Copy"/>
</div>
</li>
</ul>
<p>As usual, there is room for <a href="https://github.com/fred-wang/Mathzilla/issues">improvements and bug fixes</a>, but that's a start. In particular
I would be happy to get
<a href="https://github.com/fred-wang/Mathzilla/issues/1">translations for the two strings of the
MathML Copy add-on</a>: "Copy MathML Formula" and "Copy TeX Source".
Also, because I used the add-on SDK these add-ons are unfortunately
only available for Firefox at the moment...
</p>Improvements to Mathematics on Wikipediaurn:md5:fbacf4ded426a4469ee41ec44833f6c22014-01-13T07:56:00+01:002014-01-13T09:01:40+01:00fredwmathmlmediawikimozillawikipedia <h2>Introduction</h2>
<div style="float: left; margin: .5em;"><img src="https://upload.wikimedia.org/wikipedia/en/8/80/Wikipedia-logo-v2.svg" width="150" height="150" alt="Wikipedia"/></div>
<p>As mentioned during the <a href="http://fred-wang.github.io/MozSummitMathML/index.html">Mozilla Summit</a> and recent <a href="http://blog.rgaiacs.com:862/2013/12/14/mathml_meeting.html">MathML</a> <a href="http://blog.rgaiacs.com:862/2014/01/10/2nd_mathml_meeting.html">meetings</a>, progress has recently be made to the way mathematical equations are handled on Wikipedia. This work has mainly be done by
the volunteer contributor Moritz Schubotz (alias Physikerwelt),
Wikimedia Foundation's developer Gabriel Wicke as well as members of
MathJax.
Moritz has been particularly involved in that project and he even
travelled from Germany to San Francisco in order to meet MediaWiki developers and spend one month to do volunteer work on this project.
Although the solution is essentially ready for a couple of months, the
review of the patches is progressing slowly.
If you wish to speed up the integration of what is probably the most
important improvements to MediaWiki Math to happen, please read
<a href="http://www.maths-informatique-jeux.com/blog/frederic/?post/2014/01/13/Improvements-to-Mathematics-on-Wikipedia#mediawiki-math-help">how you can help</a>
below.
</p>
<div style="clear: both;"></div>
<h2>Current Status</h2>
<p>The approach that has been used on Wikipedia so far is the
following:</p>
<ul>
<li>
<strong>Equations are written in LaTeX</strong>
or more precisely, using a specific
set of LaTeX commands accepted by
<a href="https://www.mediawiki.org/wiki/Texvc">texvc</a>. One issue
for the MediaWiki developers is that this program is written in
OCaml and no longer maintained, so they would like to switch to a more
modern setup.
</li>
<li>
texvc calls the LaTeX program to convert the LaTeX source into <strong>PNG images</strong> and this is the default mode.
Unfortunately, using images for representing mathematical equations
on the Web
leads to classical problems (for example alignment or rendering quality
just to mention a few of them)
that can not be addressed without changing the
approach.
</li>
<li>
For a long time, registered users have been able to <strong>switch to the MathJax mode</strong> thanks to the help of <a href="https://en.wikipedia.org/wiki/User:Nageh">nageh</a>, a member of the MathJax community.
This mode solves many of the issues with PNG images but
unfortunately it adds its own problems,
<a href="http://www.mail-archive.com/wikitech-l@lists.wikimedia.org/msg70161.html">some of them being just unacceptable for MediaWiki developers</a>. Again, these issues are intrinsic to the use
of a Javascript polyfill and thus yet another approach is necessary for
a long-term perspective.
</li>
<li>Finally, registered users can also switch to the LaTeX source mode, that is only display the text source of equations.</li>
</ul>
<h2>Short Term Plan</h2>
<p>Native MathML is the appropriate way to fix all the issues regarding the display of mathematical formulas in browsers. However, the language is still not perfectly implemented in Web rendering engines, so some fallback is necessary. The new approach will thus be:</p>
<ul>
<li>The TeX equation will still be edited by hand but it will be
<strong>possible to use a visual editor</strong>.</li>
<li><strong>texvc will be used as a filter to validate the TeX source</strong>.
This
will ensure that only the texvc LaTeX syntax is accepted and will avoid
other potential security issues.
The LaTeX-to-PNG conversion as well as OCaml language will be kept in
the short term, but the plan is to drop the former and to replace the
latter with a a PHP equivalent.</li>
<li>A <strong>LaTeX-to-MathML conversion</strong> followed
by a <strong>MathML-to-SVG conversion</strong> will be
performed <strong>server-side using MathJax</strong>.</li>
<li>By default all the users will receive the same output (MathML+SVG+PNG) but only one will be made visible, according your browser capabilities. As a
first step, <strong>native MathML will only be used in Gecko</strong>
and other <strong>rendering engines will see the SVG/PNG fallback</strong> ; but the goal is to progressively drop the old PNG output and to move
to native MathML.</li>
<li><strong>Registered users</strong> will still be able to switch to the <strong>LaTeX source mode</strong>.</li>
<li><strong>Registered users</strong> will still be able to use <strong>MathJax client-side</strong>, especially if they want to use the HTML-CSS output. However, this is
will no longer be a separate mode but an option to enable. That is, the MathML/SVG/PNG/Source is displayed normally and progressively replaced with MathJax's output.</li>
</ul>
<p>Most of the features above have already been approved and integrated in the development branch or are undergoing review process.</p>
<h2 id="mediawiki-math-help">How can you help?</h2>
<div style="float: right; margin: .5em;"><img src="https://upload.wikimedia.org/wikipedia/commons/0/01/MediaWiki-smaller-logo.png" width="180" height="170" alt="MediaWiki"/></div>
<p>The main point is that
<strong>everybody can review the patches on Gerrit</strong>.
If you know about Javascript and/or PHP, if you are interested in math
typesetting and wish to get involved in an important Open Source project
such as Wikipedia then it is definitely the right time to help
the MediaWiki Math project. The article
<a href="http://www.mediawiki.org/wiki/How_to_become_a_MediaWiki_hacker">How to become a MediaWiki hacker</a> is a very good introduction.</p>
<p>When getting involved in a new open source project one of the most
important step is to set up the development environment. There are
various ways to setup a local installation of MediaWiki but
using
<a href="https://www.mediawiki.org/wiki/MediaWiki-Vagrant">MediaWiki-Vagrant</a> might be the simplest one: just follow the
<strong>Quick Start Guide</strong> and use
<code>vagrant enable-role math</code> to
<strong>enable the Math Extension</strong>.</p>
<p>The second step is to <a href="https://wikitech.wikimedia.org/wiki/Special:UserLogin/signup">create a WikiTech account</a> and to set up the appropriate
<a href="https://gerrit.wikimedia.org/r/#/settings/ssh-keys">SSH keys</a> on your MediaWiki-Vagrant virtual machine.
Then you can <a href="https://gerrit.wikimedia.org/r/#/projects/mediawiki/extensions/Math,dashboards/default">check the Open Changes</a>,
test & review them. The <a href="https://www.mediawiki.org/wiki/Gerrit/Code_review">Gerrit code review guide</a> may helpful, here.</p>
<p>If you need more information, you can ask
<a href="https://plus.google.com/104541687836095789339/posts">Moritz</a>
or try to reach people on the
<code>#mediawiki</code> (<a href="https://www.freenode.net/">freenode</a>) or <code>#mathml</code> (<a href="https://wiki.mozilla.org/IRC">mozilla</a>) channels. Thanks in advance for your help!</p>
<div style="clear: both;"></div>Funding MathML Developments in Gecko and WebKit (part 2)urn:md5:9faec7080006a98ebfb7b63a009f9eca2014-01-05T19:36:00+01:002014-01-05T20:45:19+01:00fredwgooglemathmlmicrosoftmozillawebkit <p>As I mentioned <a href="http://www.maths-informatique-jeux.com/blog/frederic/?post/2013/10/12/Funding-MathML-Developments-in-Gecko-and-WebKit">three months ago</a>, I wanted to start a crowdfunding campaign so that I can have more time to devote to MathML developments in browsers and (at least for Mozilla) continue to mentor volunteer contributors. Rather than doing several crowdfunding campaigns for small features, I finally decided to do a single crowdfunding campaign with <a href="http://www.ulule.com/">Ulule</a> so that I only have to worry only once about the funding. This also sounded more convenient for me to rely on some French/EU website regarding legal issues, taxes etc. Also, just like <a href="http://www.kickstarter.com/">Kickstarter</a> it's possible with Ulule to offer some "rewards" to backers according to the level of contributions, so that gives a better way to motivate them.</p>
<p>As everybody following MathML activities noticed, big companies/organizations do not want to significantly invest in funding MathML developments at the moment. So the rationale for a crowdfunding campaign is to rely on the support of the current community and on the help of smaller companies/organizations that have business interest in it. Each one can give a small contribution and these contributions sum up in enough money to fund the project. Of course this model is probably not viable for a long term perspective, but at least this allows to start something instead of complaining without acting ; and to show bigger actors that there is a demand for these developments. As indicated on the Ulule Website, this is a way to start some relationship and to build a community around a common project. My hope is that it could lead to a long term funding of MathML developments and better partnership between the various actors.</p>
<p>Because one of the main demand for MathML (besides accessibility) is in EPUB, I've included in the project goals a collection of documents that demonstrate advanced Web features with native MathML. That way I can offer more concrete rewards to people and federate them around the project. Indeed, many of the work needed to improve the MathML rendering requires some preliminary "code refactoring" which is not really exciting or immediately visible to users...</p>
<p>Hence I launched the crowdfunding campaign the 19th of November and <strong>we reached 1/3 of the minimal funding goal in only three days</strong>! This was mainly thanks to the support of individuals from the MathML community. In mid december we reached the minimal funding goal after a significant contribution from the <a href="http://www.maths-informatique-jeux.com/blog/frederic/?post/2014/01/05/kwarc.info">KWARC Group</a> (<a href="https://en.wikipedia.org/wiki/Jacobs_University_Bremen">Jacobs University Bremen</a>, Germany) with which I have been in communication since the launch of the campaign. Currently, we are at 125% and this means that, minus the Ulule commision and my social/fiscal obligations, I will be able to work on the project during about 3 months.</p>
<div style="width: 362px; margin-right: auto; margin-left: auto;">
<a href="http://www.ulule.com/mathematics-ebooks/">
<img src="http://www.maths-informatique-jeux.com/ulule/proposal/ulule.png" width="362" height="162" alt="MathML crowdfunding"/>
</a>
</div>
<p><strong>I'd like to thank again all the companies, organizations and people who have supported the project so far! The crowdfunding campaign continues until the end of January so I hope more people will get involved.</strong> If you want better MathML in Web rendering engines and ebooks then please support this project, even a symbolic contribution. If you want to do a more significant contribution as a company/organization then note that Ulule is only providing a service to organize the crowdfunding campaign but otherwise the funding is legally treated the same <a href="http://fr.vox.ulule.com/obligations-comptables-auto-entrepreneurs-et-traitement-en-comptabilite-fonds-recus-ulule-2931/">as required by my self-employed status</a>; feel free to contact me for any questions on the project or funding and discuss the long term perspective.</p>
<p>Finally, note that I've used my savings and I plan to continue like that until the official project launch in February. Below is a summary of what have been done during the five weeks before the holiday season. This is based on my <a href="http://www.ulule.com/mathematics-ebooks/news/">weekly updates for supporters</a> where you can also find references to the Bugzilla entries. Thanks to the Apple & Mozilla developers who spent time to review my patches!</p>
<h2>Collection of documents</h2>
<p>The goal is to show how to use existing tools (LaTeXML, itex2MML, tex4ht etc) to build EPUB books for science and education using Web standards. The idea is to cover various domains (maths, physics, chemistry, education, engineering...) as well as Web features. Given that
<a href="https://wiki.mozilla.org/ScienceLab">many scientific circles are too much biased by "math on paper / PDF" and closed research practices</a>, it may look innovative to use the Open Web but to be honest the MathML language and its integration with other Web formats is well established for a long time. Hence in theory it should "just work" once you have native MathML support, without any circonvolutions or hacks. Here are a couple of features that are tested in the sample EPUB books that I wrote:</p>
<ul>
<li>Rendering of MathML equations (of course!). Since the screen size and resolution vary for e-readers, automatic line breaking / reflowing of the page is "naturally" tested and is an important distinction with respect to paper / PDF documents.</li>
<li>CSS styling of the page and equations. This includes using (Web) fonts,
which are very important for mathematical publishing.</li>
<li>Using SVG schemas and how they can be mixed with MathML equations.</li>
<li>Using non-ASCII (Arabic) characters and RTL/LTR rendering of both the text and equations.</li>
<li>Interactive document using Javascript and <code><maction></code>, <code><input></code>, <code><button></code> etc. For those who are curious, I've created some videos for an <a href="http://www.youtube.com/watch?v=imIwtZ-mNcc">algebra course</a> and a <a href="http://www.youtube.com/watch?v=otlUBb_gtdY">lab practical</a>.</li>
<li>Using the <code><video></code> element to include short sequences of an experiment in a physics course.</li>
<li>Using the <code><canvas></code> element to draw graphs of functions or of physical measurements.</li>
<li>Using WebGL to draw interactive 3D schemas. At the moment, I've only adapted a chemistry course and used <a href="http://www.chemdoodle.com/">ChemDoodle</a> to load Crystallographic Information Files (CIF) and provide 3D-representation of crystal structures. But of course, there is not any problem to put <a href="http://www.maths-informatique-jeux.com/international/mathml-in-webgl/index.html">MathML equations in WebGL</a> to create other kinds of scientific 3D schemas.</li>
</ul>
<div style="width: 362px; margin-right: auto; margin-left: auto;">
<a href="http://www.ulule.com/mathematics-ebooks/">
<img src="http://www.maths-informatique-jeux.com/ulule/proposal/ebookmath.png" width="320" height="180" alt="MathML crowdfunding"/>
</a>
</div>
<h2>WebKit</h2>
<p>I've finished some work started as a MathJax developer, including the maction support requested by the KWARC Group. I then tried to focus on the main goals: rendering of token elements and more specifically operators (spacing and stretching).</p>
<ul>
<li>I improved LTR/RTL handling of equations (full RTL support is not implemented yet and not part of the project goal).</li>
<li>I improved the maction elements and implemented the toggle actiontype.</li>
<li>I refactored the code of some "mrow-like" elements to make them all behave like an <code><mrow></code> element. For example while WebKit stretched (some) operators in <code><mrow></code> elements it could not stretch them in <code><mstyle></code>, <code><merror></code> etc Similarly, this will be needed to implement correct spacing around operators in <code><mrow></code> and other "mrow-like" elements.</li>
<li>I analyzed more carefully the vertical stretching of operators. I see at least two serious bugs to fix: baseline alignment and stretch size. I've uploaded an experimental patch to improve that.</li>
<li>Preliminary work on the MathML Operator Dictionary. This dictionary contains various properties of operators like spacing and stretchiness and is fundamental for later work on operators.</li>
<li>I have started to refactor the code for mi, mo and mfenced elements. This is also necessary for many serious bugs like the operator dictionary and the style of mi elements.</li>
<li>I have written a patch to restore support for foreign objects in annotation-xml elements and to implement the same selection algorithm as Gecko.</li>
</ul>
<h2>Gecko</h2>
<p>I've continued to clean up the MathML code and to mentor volunteer contributors. The main goal is the support for the Open Type MATH table, at least for operator stretching.</p>
<ul>
<li>Xuan Hu's work on the <code><mpadded></code> element landed in trunk. This element is used to modify the spacing of equations, for example by some TeX-to-MathML generators.</li>
<li>On Linux, I fixed a bug with preferred widths of MathML token elements. Concretely, when equations are used inside table cells or similar containers there is a bug that makes equations overflow the containers. Unfortunately, this bug is still present on Mac and Windows...</li>
<li>James Kitchener implemented the mathvariant attribute (e.g used by some tools to write symbols like double-struck, fraktur etc). This also fixed remaining issues with preferred widths of MathML token elements. Khaled Hosny started
to update his Amiri and XITS fonts to add the glyphs for Arabic mathvariants.</li>
<li>I finished Quentin Headen's code refactoring of mtable. This allowed to fix some bugs like bad alignment with columnalign. This is also a preparation for future support for rowspacing and columnspacing.</li>
<li>After the two previous points, it was finally possible to remove the private "_moz-" attributes. These were visible in the DOM or when manipulating MathML via Javascript (e.g. in editors, tree inspector, the html5lib etc)</li>
<li>Khaled Hosny fixed a regression with script alignments. He started to work on improvements regarding italic correction when positioning scripts. Also, James Kitchener made some progress on script size correction via the Open Type "ssty" feature.</li>
<li>I've refactored the stretchy operator code and prepared some patches to read the OpenType MATH table. You can try experimental support for new math fonts with e.g. <a href="http://www.wg9s.com/mozilla/firefox/">Bill Gianopoulos' builds</a> and the <a href="https://developer.mozilla.org/en-US/docs/Mozilla/MathML_Project/MathML_Torture_Test">MathML Torture Tests</a>.</li>
</ul>
<h2>Blink/Trident</h2>
<p>MathML developments in Chrome or Internet Explorer is not part of the
project goal,
even if obviously MathML improvements to WebKit could
<a href="https://code.google.com/p/chromium/issues/detail?id=152430#c85">hopefully be imported to Blink in the future</a>. <a href="https://connect.microsoft.com/IE/SearchResults.aspx?SearchQuery=mathml">Users keep asking for MathML in IE</a> and I hope that a solution will be found <a href="http://news.dessci.com/2013/10/microsoft-cripples-display-math-ie10-11.html"> to save MathPlayer's work</a>. In the meantime, I've sent a proposal to <a href="https://code.google.com/p/chromium/issues/detail?id=324764">Google</a> and <a href="https://connect.microsoft.com/IE/feedback/details/812595/add-some-css-rules-to-select-mathml-annotations-and-alttext">Microsoft</a> to implement fallback content (<code>alttext</code> and <code>semantics</code> annotation) so that authors can use it. This is just a couple of CSS rules that could be integrated in the user agent style sheet. Let's see which of the two companies is the most reactive...
</p>
<div style="width: 362px; margin-right: auto; margin-left: auto;">
<a href="http://www.ulule.com/mathematics-ebooks/">
<img src="http://www.maths-informatique-jeux.com/ulule/proposal/electronicVSpaper.png" width="320" height="180" alt="electronic VS paper"/>
</a>
</div>Decomposition of 2D-transform matricesurn:md5:a6a6bc633aeb7335bb4cd7d93f45a7032013-12-01T18:09:00+01:002013-12-05T23:29:29+01:00fredwlinear algebramathmlmozillasvg <script type="text/javascript">
var TransformName = null;
var CSSdecomposition, SVGdecomposition, MatrixDecomposition;
function initTransformName()
{
// Initialize TransformName with the appropriate CSS property name.
if (TransformName) return true;
var test = document.getElementById("test");
var nameList = ["transform", "-moz-transform", "-webkit-transform",
"-o-transform"];
for (var i in nameList) {
TransformName = nameList[i];
if (getComputedStyle(test)[TransformName] === "none") return true;
}
return false;
}
function radToDeg(a)
{
// Radian to degree.
return 180 * a / Math.PI;
}
function mn(x)
{
// MathML Number.
if (x < 0)
return "<mrow><mo>−</mo><mn>"+Math.abs(x)+"</mn></mrow>";
return "<mn>"+x+"</mn>";
}
function trig(func, arg)
{
// MathML trigonometric function.
return "<mrow><mi>"+func+"</mi><mo>⁡</mo><mrow><mo>(</mo>"+
mn(arg / Math.PI)+"<mi>π</mi><mo>)</mo></mrow></mrow>";
}
function matrix(a, b, c, d, e, f)
{
// MathML 2D matrix.
return "<mrow><mo>(</mo><mtable><mtr><mtd>"+a+"</mtd><mtd>"+c+"</mtd><mtd>"+e+"</mtd></mtr><mtr><mtd>"+b+"</mtd><mtd>"+d+"</mtd><mtd>"+f+"</mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>1</mn></mtd></mtr></mtable><mo>)</mo></mrow>"
}
function newTranslate(tx, ty)
{
// Add a translate.
if (tx == 0 && ty == 0) return;
MatrixDecomposition +=
matrix(mn(1), mn(0), mn(0), mn(1), mn(tx), mn(ty));
if (ty == 0) {
SVGdecomposition += "translate(" + tx + ") ";
CSSdecomposition += "translate(" + tx + "px) ";
} else {
SVGdecomposition += "translate(" + tx + ", " + ty + ") ";
CSSdecomposition += "translate(" + tx + "px, " + ty + "px) ";
}
}
function newScale(sx, sy)
{
// Add a scale.
if (sx == 1 && sy == 1) return;
MatrixDecomposition +=
matrix(mn(sx), mn(0),
mn(0), mn(sy), mn(0), mn(0));
var s = "scale(" + sx + (sx == sy ? "" : "," + sy) + ") ";
SVGdecomposition += s;
CSSdecomposition += s;
}
function newRotate(a)
{
// Add a rotation.
if (a == 0) return "";
MatrixDecomposition +=
matrix(trig("cos", a), trig("sin", a),
trig("sin", -a), trig("cos", a), mn(0), mn(0));
a = radToDeg(a);
SVGdecomposition += "rotate(" + a + ") ";
CSSdecomposition += "rotate(" + a + "deg) ";
}
function newSkewX(a)
{
// Add a skewX.
if (a == 0) return;
MatrixDecomposition +=
matrix(mn(1), mn(0),
trig("tan", a), mn(1), mn(0), mn(0), mn(0));
a = radToDeg(a);
SVGdecomposition += "skewX(" + a + ") ";
CSSdecomposition += "skewX(" + a + "deg) ";
}
function newSkewY(a)
{
// Add a skewY.
if (a == 0) return;
MatrixDecomposition +=
matrix(mn(1), trig("tan", a),
mn(0), mn(1), mn(0), mn(0), mn(0));
a = radToDeg(a);
SVGdecomposition += "skewY(" + a + ") ";
CSSdecomposition += "skewY(" + a + "deg) ";
}
function decompose()
{
// Verify if a CSS transform is available.
if (!initTransformName())
throw "Your browser does not support CSS transforms."
// Apply the transform specified by the user.
var cssRect1 = document.getElementById("cssRect1");
var CSS2Dtransform = document.getElementById("CSS2Dtransform").value;
cssRect1.style[TransformName] = "none";
cssRect1.style[TransformName] = CSS2Dtransform;
// Get the matrix computed by the rendering engine.
var CSS2Dmatrix = getComputedStyle(cssRect1)[TransformName];
var regexp = /matrix\((.*),(.*),(.*),(.*),(.*),(.*)\)/;
var match = regexp.exec(CSS2Dmatrix);
if (match === null)
throw "Syntax Error. Please enter a valid CSS 2D transform."
var a = parseFloat(match[1]);
var b = parseFloat(match[2]);
var c = parseFloat(match[3]);
var d = parseFloat(match[4]);
var e = parseFloat(match[5]);
var f = parseFloat(match[6]);
document.getElementById("CSS2Dmatrix").innerHTML = CSS2Dmatrix;
document.getElementById("CSS2DmatrixMathML").innerHTML =
"<math display='block'>" +
matrix(mn(a), mn(b), mn(c), mn(d), mn(e), mn(f)) + "</math>"
// Apply the decomposition algorithm.
CSSdecomposition = ""; SVGdecomposition = ""; MatrixDecomposition = "";
newTranslate(e, f);
var Delta = a * d - b * c;
if (document.getElementById("decompo").value == "QR-like") {
// Apply the QR-like decomposition.
if (a != 0 || b != 0) {
var r = Math.sqrt(a*a+b*b);
newRotate(b > 0 ? Math.acos(a/r) : -Math.acos(a/r));
newScale(r, Delta/r);
newSkewX(Math.atan((a*c+b*d)/(r*r)));
} else if (c != 0 || d != 0) {
var s = Math.sqrt(c*c+d*d);
newRotate(Math.PI/2 - (d > 0 ? Math.acos(-c/s) : -Math.acos(c/s)));
newScale(Delta/s, s);
newSkewY(Math.atan((a*c+b*d)/(s*s)));
} else { // a = b = c = d = 0
newScale(0, 0);
}
} else {
// Apply the LU-like decomposition.
if (a != 0) {
newSkewY(Math.atan(b/a));
newScale(a, Delta/a);
newSkewX(Math.atan(c/a));
} else if (b != 0) {
newRotate(Math.PI / 2);
newScale(b, Delta/b);
newSkewX(Math.atan(d/b));
} else { // a = b = 0
newScale(c, d);
newSkewX(Math.PI/4);
newScale(0, 1);
}
}
// Display something if the transform is the identity.
if (MatrixDecomposition === "") {
MatrixDecomposition =
matrix(mn(1), mn(0), mn(0), mn(1), mn(0), mn(0));
CSSdecomposition = SVGdecomposition = "scale(1)";
}
// Display the result.
document.getElementById("SVGdecomposition").innerHTML =
SVGdecomposition;
document.getElementById("CSSdecomposition").innerHTML =
CSSdecomposition;
document.getElementById("MatrixDecomposition").innerHTML =
"<math display='block'>"+MatrixDecomposition+"</math>"
// Apply the (decomposed) transformation to the SVG and CSS elements.
document.getElementById("svgRect").
setAttribute("transform", SVGdecomposition);
cssRect2.style[TransformName] = CSSdecomposition;
}
function run()
{
var error = document.getElementById("error");
try {
error.innerHTML = "";
decompose();
} catch (e) {
error.innerHTML = e;
}
}
function update(v)
{
if (v === "") return;
document.getElementById("CSS2Dtransform").value = v;
run();
}
</script>
<p><strong>Note: some parts of this blog post (especially the Javascript program) may be lost when exported to Planet or other feed aggregators. Please view it on the original page.</strong></p>
<p>I recently took a look at the description of the CSS 2D / SVG transform
<code>matrix(a, b, c, d, e, f)</code> on MDN and I added a
<a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#General_Transformation">concrete example</a> showing the effect of such a
transform on an SVG line, in order to make this clearer for people who
are not familiar with affine transformations or matrices.
</p>
<div id="test" style="transform: none; -moz-transform: none; -webkit-transform: none; -o-transform: none;"></div>
<p>This also recalled me a small algorithm to decompose an arbitrary
SVG transform into a composition of basic transforms (Scale, Rotate,
Translate and Skew) that I wrote 5 years ago for the Amaya SVG
editor.
I translated it into Javascript and I make it available here. Feel free
to copy it on MDN or anywhere else. The convention used to represent
transforms as 3-by-3 matrices
is the one of the <a href="http://www.w3.org/TR/SVG/coords.html#TransformMatrixDefined">SVG specification</a>.</p>
<h2>Live demo</h2>
<p>Enter the <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/transform#CSS_transform_functions">CSS 2D transform</a> you want to
reduce and decompose or pick one example from the list
<select id="examples" onchange="update(this.value);">
<option value="" selected="selected">-- select a transform --</option>
<option value="matrix(1, 0, 0, 1, -40, 0)">Translate 1</option>
<option value="matrix(1, 0, 0, 1, 20, -30)">Translate 2</option>
<option value="matrix(-2, 0, 0, 1, 0, 0)">Scale 1</option>
<option value="matrix(1, 0, 0, .5, 0, 0)">Scale 2</option>
<option value="matrix(1.5, 0, 0, 1.5, 0, 0)">Scale 3</option>
<option value="matrix(.75, 0, 0, -1.5, 0, 0)">Scale 4</option>
<option value="matrix(0, 1, -1, 0, 0, 0)">Rotate 1</option>
<option value="matrix(0.7071067811865476, -0.7071067811865475, 0.7071067811865475, 0.7071067811865476, 0, 0)">Rotate 2</option>
<option value="matrix(0.5000000000000001, 0.8660254037844386, -0.8660254037844386, 0.5000000000000001, -15.98076211353316, -32.320508075688764)">Rotate 3</option>
<option value="matrix(1, 1, 0, 1, 0, 0)">Skew 1</option>
<option value="matrix(1, 0, -1, 1, 0, 0)">Skew 2</option>
<option value="matrix(15, 3, 10, 2, 40, -5)">NonInvertible</option>
<option value="matrix(.5, 0, 0, 1.5, 30, -20)">Example 1</option>
<option value="matrix(0, .75, 1.5, 0, 10, 15)">Example 2</option>
<option value="matrix(0.5, -1, 1, 0.5, 10, -20)">Example 3</option>
<option value="matrix(1, .25, -.125, 2, 20, 5)">Example 4</option>
<option value="matrix(1, -.125, .25, 2, 10, 0)">Example 5</option>
<option value="matrix(1, 0.17632698070846498, 0.36397023426620234, 1.064177772475912, 0, 0)">Example 6</option>
<option value="matrix(0, .5, -1, 1, 10, 5)">Example 7</option>
<option value="translate(25px,60px) skewX(20deg) matrix(1,3,.5,.2,1,6) rotate(20deg) translate(-20px,5px) scale(.5, .75)">Complex 1</option>
<option value="scale(1,-1) translate(5px,-50px) scale(1,.6) rotate(30deg) scale(.5,1) matrix(2, -.3, .7, 1,90, 20) translate(-17px,33px) skewX(30deg) matrix(1,2,3,4,5,6) skewX(-67deg)">Complex 2</option>
<option value="scale(.5,.8) translate(20px,-10px) matrix(-4, 2, 3, -1, -3, 17) matrix(1, 2, 3, 4, 5, 6)">Complex 3</option>
<option value="translate(50px,-10px) scaleX(1.1) matrix(0.819152, 0.573576, -0.573576, 0.819152, -20, 15) translateX(-20px) scaleY(.8) rotate(20deg) translateY(15px) scale(1.5,1.1)">Complex 4</option>
</select>. You can also choose between LU-like or QR-like decomposition:
<select id="decompo" onchange="run();">
<option value="QR-like" selected="selected">QR-like</option>
<option value="LU-like">LU-like</option>
</select>.
</p>
<div>
<input id="CSS2Dtransform" type="text" value="matrix(1, 0, 0, 1, 0, 0)" size="50" onchange="run()"></input>
<button onclick="run()">Reduce and Decompose</button>
</div>
<div><strong id="error" style="color: red;"></strong></div>
<div style="width: 200px; height: 200px; background: red; margin: auto;">
<div style="transform: translate(50px, 50px);
-moz-transform: translate(50px, 50px);
-webkit-transform: translate(50px, 50px);
-o-transform: translate(50px, 50px);
width: 100px; height: 100px;
transform-origin: 50px, 50px;
-moz-transform-origin: translate(50px, 50px);
-webkit-transform-origin: translate(50px, 50px);
-o-transform-origin: translate(50px, 50px);">
<div id="cssRect1">
<div style="width: 100px; height: 100px; background: blue;">
<span style="font-size: 40px; color: #ff0;">CSS</span>
</div>
</div>
</div>
</div>
<p>Here is the reduced CSS/SVG matrix as computed by your rendering engine <strong id="CSS2Dmatrix">?</strong> and its matrix representation:</p>
<p id="CSS2DmatrixMathML">
</p>
<p>After simplification (and modulo rounding errors), an SVG
decomposition into simple transformations is <strong id="SVGdecomposition">?</strong> and it renders
like this:</p>
<div style="width: 200px; height: 200px; background: red; margin: auto;">
<svg width="200px" height="200px">
<g transform="translate(100,100)">
<g id="svgRect">
<g transform="translate(-50,-50)">
<rect width="100px" height="100px" stroke="none" fill="blue"></rect>
<text y="40" style="font-size: 40px; fill: #ff0;">SVG</text>
</g>
</g>
</g>
</svg>
</div>
<p>After simplification (and modulo rounding errors), a CSS decomposition
into simple transformations is <strong id="CSSdecomposition">?</strong> and it renders like this:</p>
<div style="width: 200px; height: 200px; background: red; margin: auto;">
<div style="transform: translate(50px, 50px);
-moz-transform: translate(50px, 50px);
-webkit-transform: translate(50px, 50px);
-o-transform: translate(50px, 50px);
width: 100px; height: 100px;
transform-origin: 50px, 50px;
-moz-transform-origin: translate(50px, 50px);
-webkit-transform-origin: translate(50px, 50px);
-o-transform-origin: translate(50px, 50px);">
<div id="cssRect2">
<div style="width: 100px; height: 100px; background: blue;">
<span style="font-size: 40px; color: #ff0;">CSS</span>
</div>
</div>
</div>
</div>
<p>A matrix decomposition of the original transform is:
<div id="MatrixDecomposition"></div>
</p>
<h2>Mathematical Description</h2>
<p>The decomposition algorithm is based on the classical
<a href="https://en.wikipedia.org/wiki/LU_decomposition">LU</a> and
<a href="https://en.wikipedia.org/wiki/QR_decomposition">QR</a>
decompositions. First remember the SVG specification: the transform
<code>matrix(a,b,c,d,e,f)</code> is represented by the matrix</p>
<math xmlns='http://www.w3.org/1998/Math/MathML' display='block'><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mi>a</mi></mtd> <mtd><mi>c</mi></mtd> <mtd><mi>e</mi></mtd></mtr> <mtr><mtd><mi>b</mi></mtd> <mtd><mi>d</mi></mtd> <mtd><mi>f</mi></mtd></mtr> <mtr><mtd><mn>0</mn></mtd> <mtd><mn>0</mn></mtd> <mtd><mn>1</mn></mtd></mtr></mtable></mrow><mo>)</mo></mrow></math>
<p>and corresponds to the affine transformation</p>
<math xmlns='http://www.w3.org/1998/Math/MathML' display='block'><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mi>x</mi></mtd></mtr> <mtr><mtd><mi>y</mi></mtd></mtr></mtable></mrow><mo>)</mo></mrow><mo>↦</mo><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mi>a</mi></mtd> <mtd><mi>c</mi></mtd></mtr> <mtr><mtd><mi>b</mi></mtd> <mtd><mi>d</mi></mtd></mtr></mtable></mrow><mo>)</mo></mrow><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mi>x</mi></mtd></mtr> <mtr><mtd><mi>y</mi></mtd></mtr></mtable></mrow><mo>)</mo></mrow><mo>+</mo><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mi>e</mi></mtd></mtr> <mtr><mtd><mi>f</mi></mtd></mtr></mtable></mrow><mo>)</mo></mrow></math>
<p>which shows the classical factorization into a composition of a linear
transformation <math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mi>a</mi></mtd> <mtd><mi>c</mi></mtd></mtr> <mtr><mtd><mi>b</mi></mtd> <mtd><mi>d</mi></mtd></mtr></mtable></mrow><mo>)</mo></mrow></math>
and a translation <math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mi>e</mi></mtd></mtr> <mtr><mtd><mi>f</mi></mtd></mtr></mtable></mrow><mo>)</mo></mrow></math>. Now let's focus on the matrix
<math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mi>a</mi></mtd> <mtd><mi>c</mi></mtd></mtr> <mtr><mtd><mi>b</mi></mtd> <mtd><mi>d</mi></mtd></mtr></mtable></mrow><mo>)</mo></mrow></math> and denote <math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mi>Δ</mi><mo>=</mo><mi>a</mi><mi>d</mi><mo>−</mo><mi>b</mi><mi>c</mi></math> its determinant. We first
consider the LDU decomposition. If <math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mi>a</mi><mo>≠</mo><mn>0</mn></math>, we can use it as a pivot and
apply one step of Gaussian's elimination:</p>
<math xmlns='http://www.w3.org/1998/Math/MathML' display='block'><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mn>1</mn></mtd> <mtd><mn>0</mn></mtd></mtr> <mtr><mtd><mo lspace="verythinmathspace" rspace="0em">−</mo><mi>b</mi><mo stretchy="false">/</mo><mi>a</mi></mtd> <mtd><mn>1</mn></mtd></mtr></mtable></mrow><mo>)</mo></mrow><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mi>a</mi></mtd> <mtd><mi>c</mi></mtd></mtr> <mtr><mtd><mi>b</mi></mtd> <mtd><mi>d</mi></mtd></mtr></mtable></mrow><mo>)</mo></mrow><mo>=</mo><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mi>a</mi></mtd> <mtd><mi>c</mi></mtd></mtr> <mtr><mtd><mn>0</mn></mtd> <mtd><mi>Δ</mi><mo stretchy="false">/</mo><mi>a</mi></mtd></mtr></mtable></mrow><mo>)</mo></mrow></math>
<p>and thus the LDU decomposition is</p>
<math xmlns='http://www.w3.org/1998/Math/MathML' display='block'><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mi>a</mi></mtd> <mtd><mi>c</mi></mtd></mtr> <mtr><mtd><mi>b</mi></mtd> <mtd><mi>d</mi></mtd></mtr></mtable></mrow><mo>)</mo></mrow><mo>=</mo><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mn>1</mn></mtd> <mtd><mn>0</mn></mtd></mtr> <mtr><mtd><mi>b</mi><mo stretchy="false">/</mo><mi>a</mi></mtd> <mtd><mn>1</mn></mtd></mtr></mtable></mrow><mo>)</mo></mrow><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mi>a</mi></mtd> <mtd><mn>0</mn></mtd></mtr> <mtr><mtd><mn>0</mn></mtd> <mtd><mi>Δ</mi><mo stretchy="false">/</mo><mi>a</mi></mtd></mtr></mtable></mrow><mo>)</mo></mrow><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mn>1</mn></mtd> <mtd><mi>c</mi><mo stretchy="false">/</mo><mi>a</mi></mtd></mtr> <mtr><mtd><mn>0</mn></mtd> <mtd><mn>1</mn></mtd></mtr></mtable></mrow><mo>)</mo></mrow></math>
<p>Hence if <math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mi>a</mi><mo>≠</mo><mn>0</mn></math>, the transform <code>matrix(a,b,c,d,e,f)</code> can be
written
<code>translate(e,f) skewY(atan(b/a)) scale(a, Δ/a) skewX(c/a)</code>.
If <math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mi>a</mi><mo>=</mo><mn>0</mn></math> and <math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mi>b</mi><mo>≠</mo><mn>0</mn></math> then we have <math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mi>Δ</mi><mo>=</mo><mo lspace="verythinmathspace" rspace="0em">−</mo><mi>c</mi><mi>b</mi></math> and we
can write (this is approximately "LU with full pivoting"):</p>
<math xmlns='http://www.w3.org/1998/Math/MathML' display='block'><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mn>0</mn></mtd> <mtd><mi>c</mi></mtd></mtr> <mtr><mtd><mi>b</mi></mtd> <mtd><mi>d</mi></mtd></mtr></mtable></mrow><mo>)</mo></mrow><mo>=</mo><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mn>0</mn></mtd> <mtd><mo lspace="verythinmathspace" rspace="0em">−</mo><mn>1</mn></mtd></mtr> <mtr><mtd><mn>1</mn></mtd> <mtd><mn>0</mn></mtd></mtr></mtable></mrow><mo>)</mo></mrow><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mi>b</mi></mtd> <mtd><mi>d</mi></mtd></mtr> <mtr><mtd><mn>0</mn></mtd> <mtd><mo lspace="verythinmathspace" rspace="0em">−</mo><mi>c</mi></mtd></mtr></mtable></mrow><mo>)</mo></mrow><mo>=</mo><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mi>cos</mi><mo stretchy="false">(</mo><mi>π</mi><mo stretchy="false">/</mo><mn>2</mn><mo stretchy="false">)</mo></mtd> <mtd><mo lspace="verythinmathspace" rspace="0em">−</mo><mi>sin</mi><mo stretchy="false">(</mo><mi>π</mi><mo stretchy="false">/</mo><mn>2</mn><mo stretchy="false">)</mo></mtd></mtr> <mtr><mtd><mi>sin</mi><mo stretchy="false">(</mo><mi>π</mi><mo stretchy="false">/</mo><mn>2</mn><mo stretchy="false">)</mo></mtd> <mtd><mi>cos</mi><mo stretchy="false">(</mo><mi>π</mi><mo stretchy="false">/</mo><mn>2</mn><mo stretchy="false">)</mo></mtd></mtr></mtable></mrow><mo>)</mo></mrow><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mi>b</mi></mtd> <mtd><mn>0</mn></mtd></mtr> <mtr><mtd><mn>0</mn></mtd> <mtd><mi>Δ</mi><mo stretchy="false">/</mo><mi>b</mi></mtd></mtr></mtable></mrow><mo>)</mo></mrow><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mn>1</mn></mtd> <mtd><mi>d</mi><mo stretchy="false">/</mo><mi>b</mi></mtd></mtr> <mtr><mtd><mn>0</mn></mtd> <mtd><mn>1</mn></mtd></mtr></mtable></mrow><mo>)</mo></mrow></math>
<p>and so the transform becomes
<code>translate(e,f) rotate(90°) scale(b, Δ/b) skewX(d/b)</code>. Finally,
if <math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mi>a</mi><mo>=</mo><mi>b</mi><mo>=</mo><mn>0</mn></math>, then we already have an LU decomposition and we can just write</p>
<math xmlns='http://www.w3.org/1998/Math/MathML' display='block'><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mn>0</mn></mtd> <mtd><mi>c</mi></mtd></mtr> <mtr><mtd><mn>0</mn></mtd> <mtd><mi>d</mi></mtd></mtr></mtable></mrow><mo>)</mo></mrow><mo>=</mo><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mi>c</mi></mtd> <mtd><mn>0</mn></mtd></mtr> <mtr><mtd><mn>0</mn></mtd> <mtd><mi>d</mi></mtd></mtr></mtable></mrow><mo>)</mo></mrow><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mn>1</mn></mtd> <mtd><mn>1</mn></mtd></mtr> <mtr><mtd><mn>0</mn></mtd> <mtd><mn>1</mn></mtd></mtr></mtable></mrow><mo>)</mo></mrow><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mn>0</mn></mtd> <mtd><mn>0</mn></mtd></mtr> <mtr><mtd><mn>0</mn></mtd> <mtd><mn>1</mn></mtd></mtr></mtable></mrow><mo>)</mo></mrow></math>
<p>and so the transform is
<code>translate(e,f) scale(c, d) skewX(45°) scale(0, 1)</code>. </p>
<p>As a consequence, we have proved that any transform
<code>matrix(a,b,c,d,e,f)</code>
can be decomposed into a product of simple
transforms. However, the decomposition is not always what we want, for example
<code>scale(2) rotate(30°)</code> will be decomposed into a product that
involves <code>skewX</code> and <code>skewY</code> instead of preserving the
nice factors.</p>
<p>We thus consider instead the QR decomposition.
If <math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mi>Δ</mi><mo>≠</mo><mn>0</mn></math>, then by applying the Gram–Schmidt process to the columns
<math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mi>a</mi></mtd></mtr> <mtr><mtd><mi>b</mi></mtd></mtr></mtable></mrow><mo>)</mo></mrow><mo>,</mo><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mi>c</mi></mtd></mtr> <mtr><mtd><mi>d</mi></mtd></mtr></mtable></mrow><mo>)</mo></mrow></math>
we obtain
</p>
<math xmlns='http://www.w3.org/1998/Math/MathML' display='block'><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mi>a</mi></mtd> <mtd><mi>c</mi></mtd></mtr> <mtr><mtd><mi>b</mi></mtd> <mtd><mi>d</mi></mtd></mtr></mtable></mrow><mo>)</mo></mrow><mo>=</mo><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mi>a</mi><mo stretchy="false">/</mo><mi>r</mi></mtd> <mtd><mo lspace="verythinmathspace" rspace="0em">−</mo><mi>b</mi><mo stretchy="false">/</mo><mi>r</mi></mtd></mtr> <mtr><mtd><mi>b</mi><mo stretchy="false">/</mo><mi>r</mi></mtd> <mtd><mi>a</mi><mo stretchy="false">/</mo><mi>r</mi></mtd></mtr></mtable></mrow><mo>)</mo></mrow><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mi>r</mi></mtd> <mtd><mo stretchy="false">(</mo><mi>a</mi><mi>c</mi><mo>+</mo><mi>b</mi><mi>d</mi><mo stretchy="false">)</mo><mo stretchy="false">/</mo><mi>r</mi></mtd></mtr> <mtr><mtd><mn>0</mn></mtd> <mtd><mi>Δ</mi><mo stretchy="false">/</mo><mi>r</mi></mtd></mtr></mtable></mrow><mo>)</mo></mrow><mo>=</mo><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mi>a</mi><mo stretchy="false">/</mo><mi>r</mi></mtd> <mtd><mo lspace="verythinmathspace" rspace="0em">−</mo><mi>b</mi><mo stretchy="false">/</mo><mi>r</mi></mtd></mtr> <mtr><mtd><mi>b</mi><mo stretchy="false">/</mo><mi>r</mi></mtd> <mtd><mi>a</mi><mo stretchy="false">/</mo><mi>r</mi></mtd></mtr></mtable></mrow><mo>)</mo></mrow><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mi>r</mi></mtd> <mtd><mn>0</mn></mtd></mtr> <mtr><mtd><mn>0</mn></mtd> <mtd><mi>Δ</mi><mo stretchy="false">/</mo><mi>r</mi></mtd></mtr></mtable></mrow><mo>)</mo></mrow><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mn>1</mn></mtd> <mtd><mo stretchy="false">(</mo><mi>a</mi><mi>c</mi><mo>+</mo><mi>b</mi><mi>d</mi><mo stretchy="false">)</mo><mo stretchy="false">/</mo><msup><mi>r</mi> <mn>2</mn></msup></mtd></mtr> <mtr><mtd><mn>0</mn></mtd> <mtd><mn>1</mn></mtd></mtr></mtable></mrow><mo>)</mo></mrow></math>
<p>where <math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mi>r</mi><mo>=</mo><msqrt><mrow><msup><mi>a</mi> <mn>2</mn></msup><mo>+</mo><msup><mi>b</mi> <mn>2</mn></msup></mrow></msqrt><mo>≠</mo><mn>0</mn></math>. In that case, the transform becomes
<code>translate(e,f) rotate(sign(b) * acos(a/r)) scale(r, Δ/r)
skewX(atan((a c + b d)/r^2))</code>. In particular, a similarity transform
preserves orthogonality and length ratio and so
<math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mi>a</mi><mi>c</mi><mo>+</mo><mi>b</mi><mi>d</mi><mo>=</mo><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mi>a</mi></mtd></mtr> <mtr><mtd><mi>b</mi></mtd></mtr></mtable></mrow><mo>)</mo></mrow><mo>⋅</mo><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mi>c</mi></mtd></mtr> <mtr><mtd><mi>d</mi></mtd></mtr></mtable></mrow><mo>)</mo></mrow><mo>=</mo><mn>0</mn></math>
and <math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mi>Δ</mi><mo>=</mo><mrow><mo>∥</mo><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mi>a</mi></mtd></mtr> <mtr><mtd><mi>b</mi></mtd></mtr></mtable></mrow><mo>)</mo></mrow><mo>∥</mo></mrow><mrow><mo>∣</mo><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mi>c</mi></mtd></mtr> <mtr><mtd><mi>d</mi></mtd></mtr></mtable></mrow><mo>)</mo></mrow><mo>∥</mo></mrow><mi>cos</mi><mo stretchy="false">(</mo><mi>π</mi><mo stretchy="false">/</mo><mn>2</mn><mo stretchy="false">)</mo><mo>=</mo><msup><mi>r</mi> <mn>2</mn></msup></math>. Hence for a
similarity transform we get
<code>translate(e,f) rotate(sign(b) * acos(a/r)) scale(r)</code> as wanted.
We also
note that it is enough to assume the weaker hypothesis
<math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mi>r</mi><mo>≠</mo><mn>0</mn></math> (that is <math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mi>a</mi><mo>≠</mo><mn>0</mn></math> or <math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mi>b</mi><mo>≠</mo><mn>0</mn></math>)
in the expression above and so the decomposition applies in that case too.
Similarly, if we let <math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mi>s</mi><mo>=</mo><msqrt><mrow><msup><mi>c</mi> <mn>2</mn></msup><mo>+</mo><msup><mi>d</mi> <mn>2</mn></msup></mrow></msqrt></math> and instead assume
<math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mi>c</mi><mo>≠</mo><mn>0</mn></math> or <math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mi>d</mi><mo>≠</mo><mn>0</mn></math> we get
</p>
<math xmlns='http://www.w3.org/1998/Math/MathML' display='block'><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mi>a</mi></mtd> <mtd><mi>c</mi></mtd></mtr> <mtr><mtd><mi>b</mi></mtd> <mtd><mi>d</mi></mtd></mtr></mtable></mrow><mo>)</mo></mrow><mo>=</mo><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mi>cos</mi><mo stretchy="false">(</mo><mi>π</mi><mo stretchy="false">/</mo><mn>2</mn><mo stretchy="false">)</mo></mtd> <mtd><mo lspace="verythinmathspace" rspace="0em">−</mo><mi>sin</mi><mo stretchy="false">(</mo><mi>π</mi><mo stretchy="false">/</mo><mn>2</mn><mo stretchy="false">)</mo></mtd></mtr> <mtr><mtd><mi>sin</mi><mo stretchy="false">(</mo><mi>π</mi><mo stretchy="false">/</mo><mn>2</mn><mo stretchy="false">)</mo></mtd> <mtd><mi>cos</mi><mo stretchy="false">(</mo><mi>π</mi><mo stretchy="false">/</mo><mn>2</mn><mo stretchy="false">)</mo></mtd></mtr></mtable></mrow><mo>)</mo></mrow><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mo>−</mo><mi>c</mi><mo stretchy="false">/</mo><mi>s</mi></mtd> <mtd><mi>d</mi><mo stretchy="false">/</mo><mi>s</mi></mtd></mtr> <mtr><mtd><mo lspace="verythinmathspace" rspace="0em">−</mo><mi>d</mi><mo stretchy="false">/</mo><mi>s</mi></mtd> <mtd><mo lspace="verythinmathspace" rspace="0em">−</mo><mi>c</mi><mo stretchy="false">/</mo><mi>s</mi></mtd></mtr></mtable></mrow><mo>)</mo></mrow><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mi>Δ</mi><mo stretchy="false">/</mo><mi>s</mi></mtd> <mtd><mn>0</mn></mtd></mtr> <mtr><mtd><mn>0</mn></mtd> <mtd><mi>s</mi></mtd></mtr></mtable></mrow><mo>)</mo></mrow><mrow><mo>(</mo><mrow><mtable rowspacing="0.5ex"><mtr><mtd><mn>1</mn></mtd> <mtd><mn>0</mn></mtd></mtr> <mtr><mtd><mo stretchy="false">(</mo><mi>a</mi><mi>c</mi><mo>+</mo><mi>b</mi><mi>d</mi><mo stretchy="false">)</mo><mo stretchy="false">/</mo><msup><mi>s</mi> <mn>2</mn></msup></mtd> <mtd><mn>1</mn></mtd></mtr></mtable></mrow><mo>)</mo></mrow></math>
<p>Hence in that case the transform is
<code>translate(e,f) rotate(90° - sign(d) * acos(-c/s)) scale(Delta/s, s) skewY(atan((a c + b d)/s^2))</code>. Finally if <math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mi>a</mi><mo>=</mo><mi>b</mi><mo>=</mo><mi>c</mi><mo>=</mo><mi>d</mi><mo>=</mo><mn>0</mn></math>, then the transform is
just
<code>scale(0,0)</code>.</p>
<p>The decomposition algorithms are now easy to write. We note that none of
them gives the best result in all the cases (compare for example how they factor
Rotate2 and Skew1). Also, for completeness we have included the noninvertible
transforms in our study
(that is <math xmlns='http://www.w3.org/1998/Math/MathML' display='inline'><mi>Δ</mi><mo>=</mo><mn>0</mn></math>) but in practice they are not really useful (try
NonInvertible).</p>Gecko-based EPUB Readers and LaTeXMLurn:md5:18aecd647845a4988d7e1c43f98d2b202013-11-07T14:00:00+01:002013-11-07T18:28:16+01:00fredwmathmlmozilla <p>This morning, <a href="http://lists.jacobs-university.de/pipermail/project-latexml/2013-November/001547.html">Deyan Ginev announced on the LaTeXML mailing list</a> that the first <em>alpha</em> version of LaTeXML with LaTeX to EPUB support is now available. This is a very good news for people willing to <a href="https://blog.mozilla.org/blog/2013/06/14/5992/">encourage researchers to move from offline formats to more modern Web formats</a>. Although, some people
had already been successful to combine LaTeX-to-XHTML converters
and XHTML-to-EPUB converters, this is the first tool that I'm aware of that can do the direct LaTeX to EPUB3 (XHTML+MathML) conversion. I already mentioned a couple of Gecko-based EPUB tools in my previous blog post, so let's have a look at three of them. Feel free to mention more Gecko-based EPUB tools in the comments, I'm particularly interested to hear about FirefoxOS applications that would be similar
to <a href="https://itunes.apple.com/us/app/id364709193">Apple's iBooks</a>.
</p>
<p>I have updated the <a href="https://github.com/fred-wang/MozSummitMathML/tree/master/LaTeXML">LaTeXML samples based on Boris Zbarsky's thesis</a> that we demonstrated at the Innovation Fairs in Santa Clara & Brussels. This shows how to generate the traditional PDF version, the Web version, the Web version with MathJax fallback and now the <a href="http://www.maths-informatique-jeux.com/blog/all-blogs/public/epub/boris-thesis.epub">EPUB version</a>! Here are some screenshots using the Firefox extension <a href="https://addons.mozilla.org/firefox/addon/lucifox">Lucifox</a>:</p>
<div style="width: 734px; margin-left: auto; margin-right: auto; text-align: center; margin-bottom: 1em;"><img src="http://www.maths-informatique-jeux.com/blog/all-blogs/public/epub/lucifox-boris-thesis-1.png" width="734" height="708" alt="Lucifox, Boris Thesis - screenshot 1"/><br/>
Boris' Thesis in Lucifox ; page 2</div>
<div style="width: 733px; margin-left: auto; margin-right: auto; text-align: center; margin-bottom: 1em;"><img src="http://www.maths-informatique-jeux.com/blog/all-blogs/public/epub/lucifox-boris-thesis-2.png" width="733" height="708" alt="Lucifox, Boris Thesis - screenshot 2"/><br/>
Boris' Thesis in Lucifox ; page 4</div>
<p>I have intentionally not shown the diagram that are incorrectly converted by LaTeXML due to missing Xy-pic support (this is still in development). However,
Gecko supports mixing SVG and MathML via the <code>foreignObject</code> element so this would not be a problem for Gecko-based EPUB readers. Here are some screenshots of an ebook about
<a href="https://en.wikipedia.org/wiki/Constructible_polygon">regular polygon that can be constructed with compass and straightedge</a> that I have created with the help of <a href="http://golem.ph.utexas.edu/~distler/blog/itex2MML.html">itex2MML</a>. They are viewed in <a href="https://addons.mozilla.org/firefox/addon/epubreader/">EPUBReader</a> which is another Firefox extension:</p>
<div style="width: 720px; margin-left: auto; margin-right: auto; margin-bottom: 1em; text-align: center;"><img src="http://www.maths-informatique-jeux.com/blog/all-blogs/public/epub/epubreader-polygons-1.png" width="720" height="563" alt="EPUBReader, Constructible Numbers"/><br/>
EPUBReader, Constructible Numbers</div>
<div style="width: 764px; margin-left: auto; margin-right: auto; margin-bottom: 1em; text-align: center;"><img src="http://www.maths-informatique-jeux.com/blog/all-blogs/public/epub/epubreader-polygons-2.png" width="764" height="534" alt="EPUBReader, Cyclic Galois Extension"/><br/>
EPUBReader, Cyclic Galois Extension</div>
<p>Lucifox and EPUBReader have a big drawback: they do not support EPUB pages with the "scripted" property. This means that you can not use Javascript to create dynamic ebooks with live samples or interactive exercices... but this is one of the reason to use Web formats! Fortunately, there is a XUL application called <a href="http://azardi.infogridpacific.com/azardi-download.html">AZARDI</a> that supports this feature. I have created another ebook that shows an interactive
course on matrices. Click on the image to see the video on YouTube:</p>
<div style="width: G99px; margin-left: auto; margin-right: auto; margin-bottom: 1em; text-align: center;"><a href="http://www.youtube.com/watch?v=imIwtZ-mNcc"><img src="http://www.maths-informatique-jeux.com/blog/all-blogs/public/epub/azardi-matrices.png" width="699" height="558" alt="AZARDI, Interactive Course on Matrices"/></a><br/>
AZARDI, Interactive Course on Matrices</div>Funding MathML Developments in Gecko and WebKiturn:md5:d698292892c248f977b3ae357b9b8c2c2013-10-12T22:55:00+02:002013-10-15T23:05:32+02:00fredwmathmlmozillawebkit <p style="font-style: italic;">update 2013-10-15: since I got feedback, I have to say that my funding plan is independent of my work at MathJax ; I'm not a MathJax employee but I have an independent contractor status. Actually, I already used my business to fund an intern for Gecko MathML developments during Summer 2011 :-)</p>
<h2>Retrospect</h2>
<p>Since last April, I have been allowed by the MathJax Consortium to dedicate a small amount of my time to do MathML development in browsers, until possibly more serious involvement later. At the same time, we mentioned this plan to Google developers but unfortunately they just decided to drop the WebKit MathML code from Blink, making external contributions hard and unwelcome...</p>
<p>Hence I have focused mainly on Gecko and WebKit: You can find the MathML bugs that have been closed during that period on <a href="https://bugzilla.mozilla.org/buglist.cgi?list_id=8185699&resolution=FIXED&resolution=DUPLICATE&resolution=---&classification=Components&chfieldto=2013-10-31&chfield=cf_last_resolved&query_format=advanced&chfieldfrom=2013-04-01&component=MathML&product=Core">bugzilla.mozilla.org</a> and <a href="https://bugs.webkit.org/buglist.cgi?query_format=advanced&short_desc_type=allwordssubstr&short_desc=&product=WebKit&component=MathML&long_desc_type=substring&long_desc=&bug_file_loc_type=allwordssubstr&bug_file_loc=&keywords_type=allwords&keywords=&bug_status=RESOLVED&resolution=FIXED&resolution=DUPLICATE&resolution=---&emailassigned_to1=1&emailtype1=substring&email1=&emailassigned_to2=1&emailreporter2=1&emailcc2=1&emailtype2=substring&email2=&bugidtype=include&bug_id=&chfieldfrom=2013-04-01&chfieldto=2013-10-31&chfield=resolution&chfieldvalue=&cmdtype=doit&order=Reuse+same+sort+as+last+time&field0-0-0=noop&type0-0-0=noop&value0-0-0=">bugs.webkit.org</a>. For Gecko, this has allowed me to finish some of the work I started as a volunteer before I was involved full-time in MathJax as well as to continue to mentor MathML contributors. Regarding WebKit, I added a few new basic features like MathML lengths, <code><mspace></code> or <code><mmultiscripts></code> while I was getting familiar with the MathML code and WebKit organization/community. I also started to work
on <code><semantics></code> and <code><maction></code>.
<strong>More importantly, I worked with Martin Robinson to address the design concerns of Google developers and a patch to fix these issues finally landed early this week.</strong></p>
<p>However, my progress has been slow so as I mentioned in my <a href="http://www.maths-informatique-jeux.com/blog/frederic/?post/2013/10/07/Post-Summit-Thoughts-on-the-MathML-Project">previous blog post</a>, I am planning to find
a way to fund MathML developments...</p>
<h2>Why funding MathML?</h2>
<p style="font-style: italic;">Note: I am assuming that the readers of this blog know why MathML is important and are aware of the benefits it can bring
to the Web community. If not, please check
<a href="http://fiduswriter.org/2013/08/06/math-in-the-browser/">Peter Krautzberger's Interview by Fidus Writer</a> or the <a href="http://fred-wang.github.io/MozSummitMathML/index.html">MozSummit MathML slides</a> for a quick introduction.
Here my point is to explain why we need more than volunteer-driven
development for MathML.</p>
<p>First the obvious thing: Volunteer time is limited so if
we really want to see serious progress in MathML support we need to give a
boost to MathML developments. e-book publishers/readers, researchers/educators who are stuck outside the Web in a LaTeX-to-PDF world, developers/users of accessibility tools or the MathML community in general want good math support in browsers now and not to wait again for 15 more years until all layout engines catch up with
Gecko or that the old Gecko bugs are fixed.
</p>
<div style="float: left; margin: .5em;">
<a href="http://www.w3.org/Math/"><img alt="MathML" width="150" height="50" src="http://www.maths-informatique-jeux.com/blog/all-blogs/public/logos/mathml-logo.png"/></a>
</div>
<div>
<p>There are classical misunderstandings from people thinking that non-native
MathML solutions and other polyfills are the future or that math on the Web could be implemented
via PNG/SVG images or Web Components.
Just open a math book and you will see
that e.g. inline equations must be correctly aligned with the text or
participate
in line wrapping. Moreover we are considering math on the Web not math on paper,
so we want it to be compatible with HTML, SVG, CSS, Javascript,
Unicode, Bidi etc and also something that is fast and responsive. Technically,
this means that a clean solution must be in the core rendering engine,
spread over several parts of the code and must have strong interaction with the
various components like the HTML5 parser, the layout tree,
the graphic and font libraries, the DOM module, the style tree and so forth.
I do not see any volunteer-driven
Blink/Gecko/WebKit feature off the top of my head that has this
characteristic and actually even SVG or any other kind of language for
graphics have less interaction with HTML than MathML has.</p>
</div>
<div>
<p>The consequence of this is that it is extremely difficult for volunteers
to get involved in native MathML
and to do quick progress because they have to understand
how the various components of the Blink/Gecko/WebKit code work and be sure to do
things correctly. Good mathematical rendering is already something hard by
itself, so that is even more complicated when you are not writing an isolated
rendering engine for math on which you can have full control.
Also, working at the Blink/Gecko/WebKit level requires technical skills above the average
so finding volunteers who can work with the high-minded engineers of
the big browser companies is not something easy.
For instance, among the enthusiastic people coming to me and
willing to help MathML in Gecko, many got stuck when e.g. they tried to build
the Firefox source or do something more advanced and I never heard back from
them.
In the other direction, Blink/Gecko/WebKit paid developers are generally
not familiar with
MathML and do not have time to learn more about it
and thus can not always provide a relevant review of the code, or they may
break something while trying to modify code they do not entirely understand.
Moreover,
both the volunteers and paid staff have only a small amount of time to do
MathML stuff while the other parts of the engine evolve very quickly,
so it's sometimes hard to keep everything in sync.
Finally,
the core layout engines have strong security requirements that are difficult to satisfy in a volunteer-driven situation...</p>
</div>
<h2>Beyond volunteer-driven MathML developments</h2>
<p>At that point, there are several options. First the lazy one: Give up
with native math rendering, only focus on features that have impact on the
widest Web audience (i.e. those that would allow browser vendors to get more market share and thus increase their profit), thank the math people for creating the Web and kindly ask them to use
whatever hacks they can imagine to display equations on the Web. Of course as a
<a href="https://www.mozilla.org/en-US/mission/">Mozillian</a>, I think people
must decide the Web they want and thus exclude this option.</p>
<p>Next there is the ingenuous option: Expect that browser companies
will understand the importance of math-on-the-Web and start investing
seriously in MathML support. However, Netscape and Microsoft
rejected the <MATH> tag from the 1995 HTML 3.0 draft and the browser
companies have kept repeating they would only rely on volunteer contributions
to move MathML forward, despite the repeated requests from MathML folks and other scientific communities. So that option is excluded too, at least in the short
to medium term.
</p>
<p>So it remains the ambitious option: Math people and other interested parties
must get together and try to fund native MathML developments. Despite the effort
of my manager at MathJax to convince partners and raise funds, my situation has
not changed much since April and it is not clear when/if the MathJax Consortium
can take the lead in native MathML developments. Given my expertise
in Gecko, WebKit and MathML, I feel the duty to do something.
Hence I wish to reorganize
my work time: Decrease my involvement in MathJax core in order to increase
my involvement in Gecko/WebKit developments. But I need the help of the
community for that purpose. If you run a business with interest for math-on-the-Web
and are willing to fund my work, then feel free to contact me directly by
mail for further discussion. In the short term, I want
to experiment with
<a href="https://en.wikipedia.org/wiki/Crowd_funding">Crowd Funding</a> as
discussed in the next section. If this is successful we can think
of a better organization for MathML developments in the long term.</p>
<div style="clear: both;"></div>
<h2>Crowd Funding</h2>
<div style="float: right">
<a href="https://www.catincan.com/">
<img alt="Catincan" width="192" height="198" src="http://www.maths-informatique-jeux.com/blog/all-blogs/public/logos/catincan.png"/>
</a>
</div>
<div>
<p>Wikipedia defines
<a href="https://en.wikipedia.org/wiki/Crowd_funding">Crowd funding</a> as
"the collective effort of individuals who network and pool their money, usually
via the Internet, to support efforts initiated by other people or organizations". There are several Crowd Funding platforms with similar rule/interface.
I am considering <a href="https://en.wikipedia.org/wiki/Catincan">Catincan</a> which is specialized in Open Source Crowd Funding, can be used by any backer/developer around the world, can rely on Bugzilla to track the bug status and
seems to have good process to collect the
fund from backers and to pay developers.
You can easily login to the Catincan Website if
you have a GitHub, Facebook or Google account (apparently
<a href="https://login.persona.org/about">Persona</a> is not supported yet...). Finally, it seems to have a communication interface between backers and
developers, so that everybody can follow the development on the funded
features.
</p>
</div>
<p>One distinctive feature of catincan is that only well-established Open
Source projects can be funded and only developers from these projects can
propose and work on the new features ; so that backers can trust that the
features will be implemented. Of course, I have been working on Gecko, WebKit and
MathML projects
so I hope people believe I sincerely want to improve
MathML support in browsers and that I have the skills to do so ;-)</p>
<p>As said in my previous blog post, it is not clear at all (at least to me)
whether Crowd Funding can be a reliable method, but it is worth trying. There are
many individuals and small businesses showing interest in MathML, without
the technical knowledge or appropriate staff to improve MathML in browsers. So if each
one fund a small amount of money, perhaps we can get something.</p>
<p>One constraint is that each feature has 60 days to reach the
funding goal. I do not have any idea about how many people are willing
to contribute to MathML and how much money they can give.
The statistical sample of projects currently funded is too small to extract relevant
information. However, I essentially see two options:
Either propose small features
and split the big ones in small steps, so that each catincat submission
will need less work/money and improvements will be progressive with
regular feedback to backers ;
or propose larger features so they look more attractive and exciting to people
and will require less frequent submissions to catincat.
At the beginning, I plan to start with the former and if the crowd funding is
successful perhaps try the latter.</p>
<div style="clear: both;"></div>
<h2>Status in Open Source Layout Engines</h2>
<p style="font-style: italic;">Note: Obviously, Open Source Crowd Funding does not apply
to Internet Explorer, which is the one main rendering engine not mentioned below. Although
Microsoft has done a great job on MathML for Microsoft Word, they did not
give any public statement about MathML in Internet Explorer and all the bug
reports for MathML have been resolved "by design" so far. If you are interested
in MathML rendering and accessibility in Internet Explorer, please check
<a href="http://news.dessci.com">Design Science blog</a> for the latest updates
and tools.</p>
<h3>Blink</h3>
<p style="font-style: italic;">Note: I am actually focusing on the history of Chromium here but of course there are other Blink-based browsers. Note that programs like QtWebEngine (formerly WebKit-based) or Opera (formerly Presto-based) lost the opportunity to get MathML support when they switched to Blink.</p>
<p>Alex Milowski and François Sausset's first MathML implementation did not
pass Google's security review. Dave Barton fixed many issues in that implementation and as far as I know, there were not any known security vulnerabilities when Dave submitted his last version. MathML was enabled in Chrome 24 but Chrome developers had some concerns about the design of the MathML implementation in WebKit, which indeed violated some assumptions of WebKit layout code. So MathML was disabled in Chrome 25 and as said in the introduction, the source code was entirely removed when they forked.</p>
<p>Currently, the <a href="http://www.chromestatus.com/features/5240822173794304">Chromium Dashboard</a> indicates that MathML is shipped in Firefox/Safari, has positive feedback from developers and is an established standard ; but the Chromium status remains "No active development".
If I understand correctly,
Google's official position is that
they do not plan to invest in MathML development but will accept external
contributions and may re-enable MathML when it is ready
(for some sense of "ready" to be defined).
Given the MathML story in
Chrome, it seems really unlikely that any volunteer will magically show up and be willing to
submit a MathML patch. Incidentally, note the
interesting work
of the ChromeVox team regarding MathML accessibility:
<a href="http://www.youtube.com/watch?v=HVviF06S1T8">Their recent video</a>
provides a good overview of what they achieve (where Volker Sorge politely regrets
that "MathML is not implemented in all browsers").
</p>
<p>Although Google's design concerns have now been addressed in WebKit, one
most serious remark from one Google engineer is that the WebKit MathML implementation is
of too low quality to be shipped so they just prefer to have no MathML
at all. As a consequence, the best short term strategy seems to be improving
WebKit MathML support and, once it is good enough, to submit a patch to
Google. <strong>The immediate corollary is that if you wish to see MathML in Chrome
or other Blink-based browsers you should
help WebKit MathML development</strong>. See the next section for
more details.
</p>
<div style="float: left; margin: .5em; padding: 2px; border: 1px solid grey;
background: #eef">
<a href="http://www.maths-informatique-jeux.com/blog/all-blogs/public/logos/chromatic.svg"><img alt="Chromatic" width="32" height="32" src="http://www.maths-informatique-jeux.com/blog/all-blogs/public/logos/chromatic.svg"/></a>
<span style="color: grey; font-family: sans-serif; font-size: 20px; vertical-align: 10px;">chromatic</span>
</div>
<p>Actually, I tried to import MathML into Blink one day this summer. However,
there were divergences between the WebKit and Blink code bases that made that
a bit difficult. I do not plan to try again anytime soon, but if someone is
interested, I have published <a href="https://github.com/fred-wang/Chromatic">my script and patch on GitHub</a>. Note there may be even more divergences now and the patch is
certainly bit-rotten. I also thought about creating/maintaining a "Chromatic"
browser (Chrome + mathematics) that would be a temporary fork to let Blink
users benefit from native MathML until it is integrated back in Blink. But
at the moment, that would probably be too much effort for one person and
I would prefer to focus on WebKit/Gecko developments for now.</p>
<div style="clear: both;"></div>
<h3>WebKit</h3>
<p>The situation in WebKit is much better. As said before, Google's concerns
are now addressed and MathML will be enabled again in all WebKit releases
soon.
Martin Robinson is interested in helping the MathML developments in
WebKit and his knowledge of fonts will be important to improve operator
stretching, which is one of the biggest issue right now.
One new volunteer contributor, Gurpreet Kaur, also started to
do some work on WebKit like support for the <code>*scriptshifts</code>
attributes or for the <code><menclose></code> element. Last but
not least, a couple of Apple/WebKit developers reviewed and accepted
patches and even helped to fix a few bugs, which made possible to move
development forward.
</p>
<div style="float: right; margin: .5em;">
<a href="http://www.maths-informatique-jeux.com/blog/all-blogs/public/logos/webkinetic.svg"><img alt="WebKineTic" width="150" height="150" src="http://www.maths-informatique-jeux.com/blog/all-blogs/public/logos/webkinetic.png"/></a>
</div>
<p>When he was still working on WebKit, Dave Barton opened <a href="https://bugs.webkit.org/show_bug.cgi?id=99623">bug 99623</a> to track the top priorities. When the bugs below and their related dependencies are fixed, I think the rendering in WebKit will be good enough to be usable for advanced math notations and WebKit will pass the <a href="http://fred-wang.github.io/AcidTestsMathML/acid1/">MathML Acid 1 test</a>.</p>
<ul>
<li><a href="https://bugs.webkit.org/show_bug.cgi?id=44208">Bug 44208</a>:
For example, in expression like
<math><mrow><mi>sin</mi><mo>⁡</mo><mo>(</mo><mi>x</mi><mo>)</mo></mrow></math>,
the "x" should be in italic but not the "sin". This is actually slightly
more complicated: It says when the default <code>mathvariant</code>
value must be <code>normal</code>/<code>italic</code>.
<code>mathvariant</code> is more like
the
<code>text-transform</code> CSS property in the sense that it remaps
some characters to the corresponding mathematical characters (italic, bold, fraktur,
double-struck...) for example
<math><mi mathvariant="fraktur">A</mi></math> (mathvariant=fraktur A)
should render exactly the same as <math><mi>𝔄</mi></math> (U+1D504).
By the way, there is the related <a href="https://bugs.webkit.org/show_bug.cgi?id=24230">bug 24230</a> on Windows, that prevents to use plane 1 characters.
The best solution will probably be to
<a href="https://bugs.webkit.org/show_bug.cgi?id=108778">implement mathvariant</a> correctly. See also Gecko's ongoing work by James Kitchener below.</li>
<li><del><a href="https://bugs.webkit.org/show_bug.cgi?id=99618">Bug 99618</a></del>: Implement <code><mmultiscripts></code>, that allows expressions like
<math><mmultiscripts><mi mathvariant="normal">C</mi><mprescripts/><mn>6</mn><mn>14</mn></mmultiscripts></math> or <math><mmultiscripts><mi>R</mi><mi>i</mi><none/><mi>j</mi><none/><mo>;</mo><none/><none/><mi>j</mi></mmultiscripts><mo>=</mo><mfrac><mn>1</mn><mn>2</mn></mfrac><mmultiscripts><mi>S</mi><mo>;</mo><none/><mi>i</mi><none/></mmultiscripts></math>. As said in the introduction, this is fixed in WebKit Nightly.</li>
<li><a href="https://bugs.webkit.org/show_bug.cgi?id=99614">Bug 99614</a>: Support for stretchy operators like in
<math><msup><mrow><mo>(</mo><mfrac><mover><mrow><msub><mi>z</mi><mn>1</mn></msub><mo>+</mo><msub><mi>z</mi><mn>2</mn></msub></mrow><mo>¯</mo></mover><mn>3</mn></mfrac><mo>)</mo></mrow><mn>4</mn></msup></math>. Currently,
WebKit can only stretch operators vertically using a few Unicode constructions
like ⎛ (U+239B) + ⎜ (U+239C) + ⎝ (U+239D) for the left parenthesis.
Essentially only similar delimiters like brackets, braces etc are supported.
For small
sizes like <math><mrow><mo>(</mo><mtext><span style="display: inline-block; height: 1.5em; width: 2px; background: red;"></span></mtext></mrow></math> or for large operators like
<math displaystyle="true"><mo>∑</mo><msup><mi>n</mi><mn>2</mn></msup></math> it is necessary to use non-unicode glyphs in various math fonts, but this
is not possible in WebKit MathML yet. All of this will require a fair amount of
work: implementing horizontal stretching, font-specific stuff,
largeop/symmetric properties etc</li>
<li><a href="https://bugs.webkit.org/show_bug.cgi?id=99620">Bug 99620</a>:
Implement the <a href="http://www.w3.org/TR/MathML3/appendixc.html">operator dictionary</a>. Currently, WebKit treats all the operators the same way, so for
example it will use the same 0.2em spacing before and after parenthesis, equal sign or invisible
operators in e.g.
<math><mi>f</mi><mo>⁡</mo><mo>(</mo><mi>x</mi><mo>)</mo><mo>=</mo><msup><mi>x</mi><mn>2</mn></msup></math>. Instead it should use the information provided by the MathML operator dictionary. This dictionary also specifies whether operators are stretchy, symmetric or
largeop and thus is related to the previous point.
</li>
<li><a href="https://bugs.webkit.org/show_bug.cgi?id=119038">Bug 119038</a>: Use the code for vertical stretchy operators to draw the radical symbols
in roots like <math><msqrt><mfrac><mn>2</mn><mn>3</mn></mfrac></msqrt></math>. Currently,
WebKit uses graphic primitives which do not give a really good rendering.</li>
<li><del><a href="https://bugs.webkit.org/show_bug.cgi?id=115610">Bug 115610</a></del>: Implement <mspace> which is used by many MathML generators
to do some spacing in mathematical formulas. As said in the introduction, this is fixed in WebKit Nightly.</li>
</ul>
<p>In order to pass the <a href="https://developer.mozilla.org/en-US/docs/Mozilla/MathML_Project/MathML_Torture_Test">Mozilla MathML torture tests</a>, at least <a href="https://bugs.webkit.org/show_bug.cgi?id=118737">displaystyle</a> and <a href="https://bugs.webkit.org/show_bug.cgi?id=118737">scriptlevel</a> must be implemented too, probably as internal CSS properties. This should also allow to pass
<a href="https://eyeasme.com/Joe/MathML/MathML_browser_test">Joe Java's MathML test</a>, although that one relies on the infamous <code><mfenced></code>
that duplicates the stretchy operator features and is implemented inconsistently
in rendering engines. I think passing the <a href="http://fred-wang.github.io/AcidTestsMathML/acid1/">MathML Acid 2 test</a> will require slightly more effort,
but I expect this goal to be achievable if I have more time to work on WebKit:</p>
<ul>
<li><del><a href="https://bugs.webkit.org/show_bug.cgi?id=115610">Bug 115610</a></del>: Implement <mspace>. Fixed!</li>
<li><a href="https://bugs.webkit.org/show_bug.cgi?id=120164">Bug 120164</a>: Implement negative spacing for <mspace> (I have an experimental patch).</li>
<li><a href="https://bugs.webkit.org/show_bug.cgi?id=85730">Bug 85730</a>: Implement <mpadded>, which is also used by MathML generators to do some tweaking of formulas. I have only done some experiments, that would be a generalization of <mspace></li>
<li><a href="https://bugs.webkit.org/show_bug.cgi?id=85733">Bug 85733</a>: Implement the <code>href</code> attribute ; well I guess the name is explicit enough to understand what it is used for! I only have some experimental patch here too. That would be mimicing what is done in SVG or HTML.</li>
<li><a href="https://bugs.webkit.org/show_bug.cgi?id=120059">Bug 120059</a> and
<a href="https://bugs.webkit.org/show_bug.cgi?id=100626">bug 100626</a>: Implement <code><maction></code> (at least partially) and <code><semantics></code>,
which have been asked by long-time MathML users Jacques Distler and Michael Kohlhase. I have patches ready for that and this could be fixed relatively soon, I just need to find time to finish the work.</li>
</ul>
<p>In general passing the MathML Acid 2 test is not too hard, you merely only need to implement those few MathML elements whose exact rendering is clearly defined by the MathML specification. Passing the <a href="http://fred-wang.github.io/AcidTestsMathML/acid3/">MathML Acid 3 test</a> is not expected in the medium term. However, the score will
naturally increase while we improve WebKit MathML implementation. The priority
is to implement what is currently known to be important to users.
To give examples of bugs not previously mentioned: Implementing <a href="https://bugs.webkit.org/show_bug.cgi?id=85729">menclose</a> or fixing various DOM issues like bugs <a href="https://bugs.webkit.org/show_bug.cgi?id=57695">57695</a>, <a href="https://bugs.webkit.org/show_bug.cgi?id=57696">57696</a> or <a href="https://bugs.webkit.org/show_bug.cgi?id=107392">107392</a>.</p>
<p>More advanced features like those mentioned in the next section for Gecko
are probably worth considering later (Open type MATH, linebreaking,
mlabeledtr...). It is worth noting that Apple has already
done some work on accessibility (with MathML being readable by VoiceOver
in iOS7), authoring and EPUB (MathML is enabled in WebKit-based ebook
readers
and <a href="https://www.apple.com/ibooks-author/">ibooks-author</a> has
an integrated LaTeX-to-MathML converter).</p>
<div style="clear: both;"></div>
<h3>Gecko</h3>
<div style="float: left; margin: .5em;">
<a href="http://www.maths-informatique-jeux.com/blog/all-blogs/public/logos/mathzilla.svg"><img alt="Mathzilla" width="150" height="150" src="http://www.maths-informatique-jeux.com/blog/all-blogs/public/logos/mathzilla.svg"/></a>
</div>
<p>In general I think I have a good relationship with the Mozilla community and most people have respect for the work that has been done by volunteers for almost 15 years now. The situation has greatly improved since I joined the project, at that time some people claimed the
<a href="https://groups.google.com/forum/#!topic/mozilla.dev.tech.mathml/GIkKITEW48A">Mozilla MathML project was dead after Roger Sidge's departure</a>.
One important point is that Karl Tomlinson has worked
on repairing the MathML support when Roger Sidge left the project. Hence
there is at least one Mozilla employee with good knowledge of MathML who
can review the volunteer patches. Another key ingredient is the work that has recently been made by Mozilla to increase engagement of the volunteer
community like good documentation on MDN, the <code>#Introduction</code> channel, Josh Matthews' <a href="http://www.joshmatthews.net/bugsahoy/">mentored bugs</a> and of course programs like GSOC. However, as said
above, it is one thing to attract enthusiastic contributors and another thing
to get long-term contributors who can work independently on more advanced features. So
let's go back to my latest <a href="http://www.maths-informatique-jeux.com/blog/frederic/?post/2012/09/01/Mozilla-MathML-Project%3A-Roadmap">Roadmap for the Mozilla MathML Project</a> and see what has been accomplished for one year:
</p>
<div style="clear: both;"></div>
<ul>
<li>Font support: Dmitry Shachnev created a Debian package for the
MathJax fonts and Mike Hommey added MathJax and Asana fonts in the list
of suggested packages for Iceweasel. The STIX fonts have also been
updated in Fedora and are installed by default on
Mac OS X Lion (10.7). For Linux distributions, it would be helpful
to implement <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=467729">Auto Installation Support</a>. The bug to
<a href="https://code.google.com/p/android/issues/detail?id=36011">add mathematical fonts to Android</a> has been assigned in June but no more progress has happened so far.
Henri Sinoven opened a <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=775060">bug for FirefoxOS</a> but there has not been any progress there either.
I had some patches to restore the "missing MathML fonts" warning (using an information bar) but it was refused by Firefox reviewers. However, the code to detect missing MathML font could still be used for the similar <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=648548">bug 648548</a>, which also seems inactive since January. There are still some issues on the MathJax side that prevent to integrate Web fonts for the native MathML output mode. So at the moment the solution is
still to inform visitors about <a href="https://developer.mozilla.org/en-US/docs/Mozilla/MathML_Project/Fonts">MathML fonts</a> or to <a href="https://developer.mozilla.org/en-US/docs/Web/MathML/Authoring#Mathematical_fonts">add MathML Web fonts</a> to your Web site. Khaled Hosny (font and LaTeX expert) recently updated my patches to prepare the support for Open Type fonts and he offered to help on that feature.
After James Kitchener's work on mathvariant, we realized that we will
probably need to provide Arabic mathematical fonts too.</li>
<li>Spacing: Xuan Hu continued to work on <mpadded> improvements and I think his patch is close to be accepted. Quentin Headen has done some progress on <mtable> before focusing on his <a href="http://clokep.blogspot.fr/2013/10/yahoo-protocol-google-summer-of-code.html">InstantBird GSOC project</a>. He is still far from being able to work on
<code>mtable@rowspacing/columnspacing</code> but a work around for that has been added
to MathJax. I fixed the negative space regression
which was missing to <a href="http://www.maths-informatique-jeux.com/blog/frederic/?post/2013/05/03/Firefox-Nightly-passes-the-Acid2-test">pass the MathML Acid 2 test</a> and is used in MathJax. Again, Khaled Hosny is willing to help to use the spacing of the Open Type MATH, but that will still be a lot of work.</li>
<li><mlabeledtr>: A work around for native MathML has been added in MathJax.</li>
<li>Linebreaking: No progress except that I have worked on fixing a bug with intrinsic width computation. The unrelated printing issues mentioned in the blog post have been fixed, though.</li>
<li>Operator Stretching: No progress. I tried to analyze the regression more carefully, but nothing is ready yet.</li>
<li>Tabular elements: As said above, Quentin Headen has worked a bit on cleaning up <mtable> but not much improvements on that feature so far.</li>
<li>Token elements: My patch for <ms> landed and I have done significant progress on the bad measurement of intrinsic width for token elements (however, the fix only seems to work on Linux right now). James Kitchener has taken over my work on improving our <code>mathvariant</code> support and doing related refactoring of the code. I am confident that he will be able to have something ready soon. The primes in exponents should render correctly with MathJax fonts but for other math fonts we will have to do some glyph substitutions.</li>
<li>Dynamic MathML: No progress here but there are not so many bugs regarding Javascript+MathML, so that should not be too serious.</li>
<li>Documentation: It is now possible to use MathML in code sample or
directly in the source code. The <a href="https://developer.mozilla.org/en-US/docs/Mozilla/MathML_Project">MathML project pages</a> have been entirely migrated to MDN. Also, Florian Scholz has recently been hired by Mozilla as
a documentation writer (congrats!) and will in particular continue the work he started as a volunteer to <a href="https://developer.mozilla.org/en-US/docs/Web/MathML">document MathML on MDN</a>.
</li>
</ul>
<p>I apologize to volunteers who worked on bugs that are not mentioned above or who are doing documentation or testing that do not appear here. For a complete list of activity since September 2012, <a href="https://bugzilla.mozilla.org/buglist.cgi?list_id=8214220&classification=Components&chfieldto=Now&query_format=advanced&chfieldfrom=2012-09-01&component=MathML&product=Core">Bugzilla is your friend</a>. There are two ways to consider the progress above.
If you see the glass half full, then you see that several people have continued
the work on various MathML issues, they have made some progress and we now pass
the MathML Acid 2 test. If you see
the glass half empty, then you see that most issues have not been addressed
yet and in particular those that are blocking the native MathML to be enabled
in MathJax: <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=687807">bug 687807</a>, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=415413">bug 415413</a>, the math font issues discussed in the first point, and perhaps linebreaking too. That is why I believe we should go beyond volunteer-driven MathML
developments.</p>
<p>Most of the bugs mentioned above are tested by the <a href="http://fred-wang.github.io/AcidTestsMathML/acid3/">MathML Acid 3 tests</a> and we will win a few points when they are fixed. Again, passing MathML Acid 3 test is not a goal by itself so let's consider what are the big remaining areas it contains:</p>
<ul>
<li>Improving Tabular Elements and Operator Stretching, which are obviously important and used a lot in e.g. MathJax.</li>
<li>Linebreaking, which as I said is likely to become fundamental with small screens and ebooks.</li>
<li>Elementary Mathematics (you know addition, subtraction, multiplication, and division that kids learn), which I suspect will be important for educational tools and ebooks.</li>
<li>Alignment: This is the one part of MathML that I am not entirely sure is relevant to work on in the short term. I understand it is useful for advanced layout but most MathML tools currently just rely on tables to do that job and as far as I know the only important engine that implements that is MathPlayer.</li>
</ul>
<p>Finally there are other features outside the MathML rendering engines that
I also find important but for which I have less expertise:</p>
<ul>
<li><a href="http://www.w3.org/TR/MathML3/chapter6.html#world-int-transfers">Transferring MathML</a> that is implementing copy/cut/drag and paste. Currently, we can do that by treating MathML as normal HTML5 code or by using the "show MathML source" feature and copying the source code. However, it would be best to implement a standard way to communicate with other MathML applications like Microsoft Word, Mathematica, Mapple, Windows' Handwriting panel etc I wrote
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=539506">some work-in-progress patches</a> last year.</li>
<li>Authoring MathML: Essentially implementing things like deletion, insertion etc maybe simple MathML token creation ; in <a href="http://dxr.mozilla.org/mozilla-central/source/editor">Gecko's core editor</a>, which is used by BlueGriffon, KompoZer, SeaMonkey, Thunderbird or even MDN. Other things like integrating Javascript parsers (e.g. ASCIIMath) or equation panels with buttons like <button><math><msqrt><mi>□</mi></msqrt></math></button> are probably better done at the higher JS/HTML/XUL level. Daniel Glazman already wrote math input panels for
<a href="http://www.bluegriffon.com/index.php?pages/MathML">BlueGriffon</a> and
<a href="http://www.glazman.org/weblog/dotclear/index.php?post/2012/11/16/MathML-and-Thunderbird">Thunderbird</a>.
</li>
<li>MathML Accessibility: This is one important application of MathML for which there is strong demand and where Mozilla is behind the competitors. James Teh started some experimental work on his NVDA tool before the summit.</li>
<li>EPUB reader for FirefoxOS (and other mobile platforms): During the
"Co-creating Action Plans" session, the Mozilla Taipei people were thinking
about missing features for FirefoxOS and this idea about EPUB reader was my modest contribution.
There are a few <a href="http://www.mathjax.org/resources/epub-readers/">EPUB readers relying on Gecko</a> and it would be good to check if they work in
FirefoxOS and if they could be integrated by default, just like
Apple has iBooks. BTW, there is a version of <a href="http://www.bluegriffon-epubedition.com/BGEE.html">BlueGriffon</a> that can edit EPUB books.
</li>
</ul>
<h2>Conclusion</h2>
<p>I hope I have convinced some of the readers about the need to fund MathMLin browsers. There is a lot of MathML work to do on Gecko and WebKit but both projects have volunteers and core engineers who are willing to help. There are also several individuals / companies relying on MathML support in rendering engines for their projects and could support the MathML developments in some way. I am willing to put more of my time on Gecko and WebKit developments, but I need financial help for that purpose. I'm proposing catincan Crowd Funding in
the short term so that anyone can contribute at the appropriate level, but other alternatives to fund the MathML development can be found like asking Peter Krautzberger about native MathML funding in MathJax,
discussing with <a href="http://www.igalia.com">Igalia</a> about funding Martin Robinson to work more on WebKit
MathML or contacting me directly to establish some kind of part-time
consulting agreement.</p>
<p>Please leave a comment on this blog or send me a private mail, if you
agree that funding MathML in browsers is important, if you like the crowd funding idea and plan to contribute ; or if you have any opinions about alternative funding options. Also, please tell me what seem to be the priority for you and
your projects among what I have mentioned above
(layout engines, features etc) or among others that I may have forgotten. Of course,
any other constructive comment to help MathML support in browsers is welcome. I plan to submit features on catincan soon, once I have more feedback on
what people are interested in. Thank you!</p>Post-Summit Thoughts on the MathML Projecturn:md5:c920a83d594eaeefdaaa58525703bdcd2013-10-07T18:06:00+02:002013-10-07T18:18:37+02:00fredwmathmlmozillamozsummit <p>
I'm back from a great Mozilla Summit 2013 and I'd just like to write
a quick blog post about the MathML booths at the Innovation Fairs.
I did not have the opportunity to talk with the MathML people who
ran the booth at Santa Clara yet. However, everything went pretty
well at Brussels, modulo of course some demos failing when done in
live... If you are interested,
<a href="https://github.com/fred-wang/MozSummitMathML#mozsummitmathml">the slides and other resources</a> are available on my GitHub page.
</p>
<p>
Many Mozillians did not know about MathML or that it
had been available in Gecko since the early days of the Mozilla project.
Many people who use math (or just knowing someone who does)
were curious about that feature and excited about the MathML potentials.
I appreciated to get this positive feedback from Mozillians willing
to use math on the Web and related media, instead of the scorn or hatred
I sometimes see by misinformed people. I expect to provide more
updates on LaTeXML, MediaWiki Math and MathJax when their next versions
are released. The Gecko MathML support improves slowly but there has
been interesting work by James Kitchener recently that I'd like to
mention too.
</p>
<div style="width: 300px; margin-left: auto; margin-right: auto;">
<img src="http://fred-wang.github.io/MozSummitMathML/mathzilla.svg"
width="300" height="300" alt="MathZilla on blackboard"/>
</div>
<p>
Let's do an estimation
<a href="https://en.wikipedia.org/wiki/Fermi_problem">à la Fermi</a>:
only a few volunteers have been contributing
regularly and simultaneously to MathML in Gecko while most
Mozilla-funded Gecko projects have certainly development teams that are
3 times as large. Let's be optimistic and assume that these
volunteers have been able to dedicate a mean of 1 work day
per week, compared to 5 for full-time staff.
Given that the Mozilla MathML project will celebrate its 15 years
next May, that means that the volunteer work
transposed in terms of paid-staff time is only
<math>
<mo>≤</mo>
<mfrac>
<mn>15</mn>
<mrow><mn>3</mn><mo>⋅</mo><mn>5</mn></mrow>
</mfrac>
<mo>=</mo>
<mn>1</mn>
</math>
year. To be honest, I'm disregarding here the great work made by the
Mozilla NZ team around 2007 to repair MathML after the Cairo migration.
But still, what we have achieved in quality and
completeness with such limited resources and time is really impressive.
</p>
<p>
As someone told me at the MathML booth, it's really frustating
that something that is so important for the small portion of
math-educated people
is ignored because it is useless for the vast majority of people. This
is not entirely true, since even elementary mathematics taught at school
like the one of
this blog post are not easily expressed with standard HTML
and even less in a way accessible to people with visual
disabilities. However, it summarizes well the feeling MathML folks had
when they tried to convince
Google to
<a href="https://code.google.com/p/chromium/issues/detail?id=152430#c32">
accept the volunteer work on MathML, despite its low quality</a>.</p>
<p>
As explained at the Summit Sessions, Mozilla's mission is different and
the goal is to give people the right to control the Web they want.
The MathML project is perhaps one of the oldest and successful
volunteer-driven Mozilla project that is still active and
demonstrates concretely the idea of the Mozilla's mission with e.g. the
work of Roger Sidge who started to write the MathML
implementation when Netscape opened its source code or the one of
Florian Scholz who made MDN one of the most complete Web resource for
MathML.
</p>
<p><a href="https://groups.google.com/forum/#!msg/mozilla.dev.tech.mathml/GIkKITEW48A/z-QvVW8pPmkJ">Mozilla Corporation has kept saying they don't want to invest in MathML developments</a> and the focus right now is clearly on other features like FirefoxOS. Even projects that have a larger audience than the MathML support like the mail client or the editor are not in the priorities so someone else definitely need to step in for MathML. I've tried various methods, with more or less success, to boost the MathML developments like mentoring a GSoC project, funding a summer internship or relying on <a href="http://www.joshmatthews.net/bugsahoy/">mentored bugs</a>. I'm now considering <a href="https://en.wikipedia.org/wiki/Crowd_funding">crowd funding</a> to help the MathML developments in Gecko (and WebKit). I don't want to do another Fermi estimation now but
at first that looks like a very unreliable method. The only revenue generated by the MathML project so far are the
<math>
<mrow>
<mn>2</mn>
<mfrac>
<mrow>
<mo>⌊</mo>
<mn>100</mn>
<mo>⋅<!-- ⋅ --></mo>
<mi>π<!-- π --></mi>
<mo>⌋</mo>
</mrow>
<mn>100</mn>
</mfrac>
<mo>=</mo>
<mn>2</mn>
<mo>⋅<!-- ⋅ --></mo>
<mn>3.14</mn>
<mo>=</mo>
<mn>6.28</mn>
</mrow>
</math> dollars to the Mozilla Fundation via contributions to
my <a href="https://addons.mozilla.org/addon/mathml-fonts/">MathML-fonts add-on</a>, so it's hard to get an idea of how much people would contribute
to the Gecko implementaton.
However, that makes sense since the only people who showed interest
in native MathML support so far are individuals or small businesses
(e.g. working on EPUB or accessibility) and I think it's worth
trying it anyway. That's definitely
something I'll consider after MathJax 2.3 is
released...</p>Firefox Nightly passes the Acid2 testurn:md5:8d65a7583b5a90787a62eb75f9dd1c992013-05-03T14:40:00+02:002013-05-03T14:43:18+02:00fredwblinkmathmlmozilla <p>Some updates on the <a
href="https://github.com/fred-wang/AcidTestsMathML/">MathML Acid Tests</a>...
First the patch for <a
href="https://bugzilla.mozilla.org/show_bug.cgi?id=717546">bug 717546</a>
landed in Nightly and thus Gecko is now the first layout engine to pass the <a
href="http://fred-wang.github.io/AcidTestsMathML/acid2/">MathML Acid2 test</a>.
Here is a screenshot that should look familiar:</p>
<p><img alt="MathML Acid2, Nightly"
src="http://www.maths-informatique-jeux.com/blog/all-blogs/public/mathml/acid2_nightly.png"
width="546" height="619" /></p>
<p>As you know, Google developers forked Webkit and decided to remove from
Blink all the code (including MathML) on which they don't plan to work in the
short term. As a comparison, here is how the MathML Acid2 test looks like in
Chrome Canary:</p>
<p><img alt="MathML Acid 2 Test, Canary"
src="http://www.maths-informatique-jeux.com/blog/all-blogs/public/mathml/acid2_canary.png"
width="552" height="621" /></p>
<p>Next, someone reported that <a
href="https://bugzilla.mozilla.org/show_bug.cgi?id=851835">Firefox Mac got more
errors</a> in the <a
href="http://fred-wang.github.io/AcidTestsMathML/acid3/">MathML Acid3 test</a>.
I was already aware of some shortcomings anyway and thus took the opportunity
to rewrite the tests with a better error tolerance. The changes also fixed some
measurement issues with auto resizing on mobile platforms or when the zoom
level is not set to the default. I also made the tests for stretchy operators
more reliable and as a consequence, Gecko lost two points: the new score is
60/100. I still need to review and describe the tests and hope I won't find
more mistakes.</p>
<p>Finally, I also added a <a
href="http://fred-wang.github.io/AcidTestsMathML/acid1/">MathML Acid1 test</a>.
It does not really look like the "classical" Acid1 test and is not "automated",
in the sense that a reader must carefully (and in a subjective way) check the
<a
href="http://fred-wang.github.io/AcidTestsMathML/acid1/description.html">basic
requirements</a>. But at least it provides a small test in the spirit of CSS
Acid 1: all 100%-conformant HTML 5 agents should be able to render these very
elementary MathML expressions. Note that the formulas in the MathML Acid1 test
are supposed to express mathematical properties of boxes from the CSS Acid1
test.</p>MathML Acid Testsurn:md5:979359b62ff8d29c9ceca7f6ae5a72532013-03-02T18:20:00+01:002013-03-02T19:19:18+01:00fredwmathmlmozilla <p>There has recently been discussion in the Mozilla community about Opera
switch from Presto to Webkit and the need to preserve browser competition and
diversity of rendering engines, especially with mobile devices. Some people
outside the community seem a bit skeptic about that argument. Perhaps a
striking example to convince them is to consider the case of MathML where
basically only Gecko has a decent native implementation and the situation in
the recent <a
href="http://www.w3.org/2013/02/11-ebooks-minutes.html">eBooks</a> <a
href="http://www.w3.org/2013/02/12-ebooks-minutes.html">workshop</a>
illustrates that very well: MathML support is very important for some publishers
(e.g. for science or education) but the main eBook readers rely
exclusively on the Webkit engine and its rudimentary MathML implementation.
Unfortunately because there is currently essentially no alternatives on mobile
platforms, developers of eBook readers have no other choices than proposing a
partial EPUB support or relying on polyfill....</p>
<p>After Google's announce to remove MathML from Chrome 25, someone
ironized on twitter about the fact that an Acid test for MathML should be
written since that seems to motivate them more than community feedback. I do
not think that MathML support is something considered important from the point
of view of browser competition but I took this idea and started writing MathML
versions of the famous Acid2 and Acid3 tests. The <a
href="https://github.com/fred-wang/AcidTestsMathML">current source of these
MathML Acid tests</a> is available on GitHub. Of course, I believe that native
MathML implementation is very important and I expect at least that these tests
could help the MathML community ; users and implementers.</p>
<p>Here is the result of the MathML Acid2 test with the stable Gecko release.
To pass the test we only need to implement negative spacing or at least
integrate the patch I submitted when I was still active in Gecko developments (<a
href="https://bugzilla.mozilla.org/show_bug.cgi?id=717546">bug 717546</a>).</p>
<p><img alt="MathML Acid2 test ; Gecko"
src="http://www.maths-informatique-jeux.com/blog/all-blogs/public/mathml/acid2gecko.png"
width="516" height="230" /></p>
<p>And here is the score of the MathML Acid 3 test with the stable Gecko
release. The failure of test 18 was not supposed to happen but I discovered it
when I wrote the test. That will be fixed by James Kitchener's refactoring in
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=827713">bug 827713</a>.
Obviously, reaching the score of 100/100 will be much more difficult to achieve
by our volunteer developers, but the current score is not too bad compared to
other rendering engines...</p>
<p><img alt="MathML Acid 3 ; Gecko"
src="http://www.maths-informatique-jeux.com/blog/all-blogs/public/mathml/acid3gecko.png"
width="582" height="289" /></p>