WordPress 1.2, MathML Goodness
Update (3/21/2005):
With WordPress 1.5, many of the troubles discussed below have gone away. A new version of the plugin, along with simplified setup procedure are detailed here.WordPress 1.2 has just been released. Congratulations to Matt and his team for numerous improvements and a shiny new plugin architecture!
In celebration of the event, I’m releasing an itexToMML plugin for WordPress 1.2 and above. This brings easy-to-use mathematical authoring to the WordPress platform.
Installation involves a few simple steps.
- First, you need to download and install the itex2MML binary. There are precompiled binaries for Linux and Windows and a precompiled MacOSX binary is included with my source distribution.
- Edit line 22 of the plugin to reflect the location where you installed the binary. By default, it says
$itex2MML = '/usr/local/bin/itex2MML';
- Install the plugin as
wp-content/plugins/itexToMML.php
- Apply the following patch, which makes sure that the installed text-filtering plugins — wptexturize, Textile (1 and 2) and Markdown — play nice with MathML content. (These changes will, hopefully, be in the next release of WordPress.)
- Activate the plugin in the administrative interface.
- Start serving your blog with the correct MIME Type.
- If you want people to be able to post comments in itex, add the requisite list of MathML tags to your
mt-hacks.php
file.
That’s the good news.
The bad news is that WordPress 1.2 has a serious bug, which renders the plugin nearly useless for serious work. Like its ancestor, b2, WordPress eats backslashes. Type “\\a” in the entry form, and “\a” gets posted to your blog. Re-edit the post, and “\a” gets turned into “a” when re-posted. Since TeX relies heavily on backslashes, this is a pretty debilitating feature. Hopefully, it’ll get fixed soon.
The other thing that is less than ideal is that enabling the plugin is all-or-nothing. When enabled, all your posts and comments get filtered through itexToMML, even those with no math in them. That’s rather wasteful of resources.
But, again, I’m pretty sure that this will have to change in subsequent versions of WordPress. Forget about the people using itexToMML. Consider the choice of text filters for composing posts. Currently, there are four: wptexturize (the default), Textile1, Textile2 and Markdown. Say you have been using Textile for a while and decide one day to switch to Markdown. Guess what? You can’t! If you disable Textile and enable Markdown, this choice applies to all your posts. But the syntaxes of these two markup dialects are incompatible. Your old posts will break horribly if you switch. Once you’ve accumulated a body of posts using one text filter, you are basically stuck, regardless of whether something better comes along, tempting you to switch.
MovableType lets you assign a choice of text filter to each of your posts individually. If you decide one day to switch from Textile to Markdown, your old posts don’t break, because they still get processed with Textile. I added the ability to assign a choice of text filter to each comment in MT. That way, commenters can compose their comments in their favourite idiom, rather than yours.
It seems to me that, once you start giving people a choice of text filters for formatting their posts, it’s inevitable that you’ll need to allow them to make that selection on a per-post basis. WordPress actually allows multiple text filters to be applied to (every) post. If you want to use itexToMML with Textile formatting, you just activate both plugins. In MovableType, I had to create a third text filter plugin, whose sole purpose was to daisy-chain the other two together. It will be cool to see how WordPress eventually handles this. Perhaps there will be a set of checkboxes in the composition window, letting you select which text filters apply to the post you’re composing.
But all that is for the future. Right now, WordPress users have a shiny new toy to play with. I hope they enjoy my small addition to the party.
MIME Types for WordPress
Those familiar with this blog will know that to get MathML to render in Gecko-based browsers (Netscape 7, Mozilla, Firefox,…) and in IE/6 with the MathPlayer 2.0 plugin, you need to serve your pages as application/xhtml+xml
. My MovableType solution involves using mod_rewrite
to set the HTTP Content-Type
headers.
In WordPress, as in any PHP-based system, it’s probably preferable to set the headers directly in your PHP code. It would be great if someone wrote up a definitive guide to doing this in WordPress. Unfortunately, most of the existing instructions, like Simon Jessey’s are written under the misapprehension that the correct thing to do is to set the Content-Type
based on the Accept
headers sent by the browser.
This is wrong. It may be “morally correct,” but it doesn’t actually work with real-world browsers.
Both Camino and Opera 7.5 include application/xhtml+xml
in their Accept
headers. Both cough up hairballs when served XHTML+MathML content with that MIME type. IE/6, with the MathPlayer 2.0 plugin installed, handles application/xhtml+xml
(either straight XHTML or XHTML+MathML) just fine, even though it doesn’t say so in its Accept
headers.
The only correct thing to do is to send the MIME type based on the User-Agent
string sent by the browser. Anybody want to take a crack at writing up some instructions for WordPress?
if ( (preg_match("/Gecko|W3C_Validator|MathPlayer/", $_SERVER["HTTP_USER_AGENT"]) && !preg_match("/Chimera|Camino|KHTML/",$_SERVER["HTTP_USER_AGENT"])) || preg_match("/Camino.*MathML-Enabled/", $_SERVER["HTTP_USER_AGENT"]) ) { header("Content-type: application/xhtml+xml; charset=utf-8"); print('<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0//EN" "http://www.w3.org/Math/DTD/mathml2/xhtml-math11-f.dtd" > <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> '); } else { header("Content-type: text/html; charset=utf-8"); print(' <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> '); }
to be placed in wp-blog-header.php
or at the top of whatever pages need to be served with the correct MIME type. Either way, you need to remove the hard-coded DOCTYPE declaration and opening <html>
tag in the affected pages.
Re: WordPress 1.2, MathML Goodness
Put
in
wp-blog-header.php
.Then remove
from all of your templates.
(You may, of course, want to send the MathML doctype to both; This is just an adaptation of what I use to send the XHTML 1.1 doctype.)