At the job, we run several instances of MediaWiki that we use for internal collaboration and to produce content that will eventually be published on a public Web site. My job generally involves building custom content management systems for various types of content. I chose to build them using Ruby on Rails. Because all of our users are already getting used to MediaWiki, we thought it would be cool to support MediaWiki’s markup format within our custom applications.
I assigned a developer to build a parser for MediaWiki Markup in Ruby, and after spending a couple of weeks of work using Racc, he threw up his hands. The parser in MediaWiki is written using regular expressions and has some oddly inconsistent behaviors. Furthermore, the language is so complex that he told me it would basically take him forever to get it finished. (There were also some features missing from Racc that were greatly complicating the task.)
Unfortunately, we told our users about our exciting MediaWiki parser project before I learned that writing such a parser was not going to be worth our time (or money). Rather than giving up, we instead created a Ruby on Rails plugin that actually shells out to PHP and calls the parser built into MediaWiki. A developer who knows PHP and Ruby on Rails well wrote the plugin in a couple of days. I still haven’t decided whether this is the worst hack in the history of the world or a brilliant solution to a thorny problem. I guess it’s probably a little of both.
The main downside is that now we have a full MediaWiki installation setting in the
vendor directory of our Rails applications, and any server that hosts our Rails application has to have PHP installed and working as well. The upside is that we didn’t have to write the parser ourselves and we don’t have to worry about keeping up with changes to MediaWiki markup as it evolves over time.
In order to forestall performance problems, the content is only parsed when it’s saved, and the HTML version of the content is stored in the database so that we don’t have to run an external shell script every time we render a piece of content.
The next step is to package this thing up and see if anybody else finds it useful.