I finally got access to a Google Wave sandbox account, making it possible to start experimenting. The first thing I made was a Latex robot. By adding the robot, it's possible to write Latex in Waves. Afterwards, simply by putting Latex between two $'s:
\lim_{n \to \infty} \frac{1}{n} = 0$$Watexy then changes the Wave and inserts the Latex as an image instead of the text.
You can try it yourself by adding watexy [this-funny-curly-a] appspot.com to your Wave-conversations. You can download the source here.
There's still a quite big bug: It's only the first Latex-image that gets substituted correctly. The following gets inserted some positions wrong, and the deletion of the text isn't correct neither. But the images itself are correct, only the substitution isn't working properly. But I'm working on that!
The more technical part: the robot is written in Python, hence using the Google Wave Python API. It's the first time I've tried that (thought it was a good possibility to learn it). The robot basically works by getting triggered when a new blip is submitted. Then it searches for Latex-code in that and substitutes it with pictures. Although the code is quite simple, it shows some very basic concepts on how to alter/change the contents of Waves on-the-fly (deleting text and inserting images, but it could be other things as well) with robots. The Latex-source-to-image is done by the http://www.forkosh.dreamhost.com/source_mathtex.html#webservice service.
The core Python comprising the robot is this:
# Python reference: # http://wave-robot-python-client.googlecode.com/svn/trunk/pydocs/index.html # Shortcut to the important OpBasedDocument # http://wave-robot-python-client.googlecode.com/svn/trunk/pydocs/waveapi.ops.OpBasedDocument-class.html """ Known bugs: - From (and including) the second Latex-fragment, the positioning gets wrong > Probably the document needs some kind of updatering > Even though it's a bit strange since the re matches all the Latex correctly """ __author__ = 'mikl@mikl.dk (Mikkel Meyer Andersen)' import re from waveapi import events from waveapi import model from waveapi import robot from waveapi import document def OnRobotAdded(properties, context): """Invoked when the robot has been added.""" root_wavelet = context.GetRootWavelet() root_wavelet.CreateBlip().GetDocument().SetText("Hi. My name is Watexy and I'm here to help you presenting Latex in waves. Just put the latex between " /> and2+2=5
) def OnBlipSubmitted(properties, context): """Invoked when a blip has been added.""" blip = context.GetBlipById(properties['blipId']) blip_text_view = blip.GetDocument() latex_regex = re.compile('\$\$(.+?)\$\$') m = latex_regex.search(blip_text_view.GetText()) """ Only replace one Latex-fragment at a time, because replaceing one fragment changes the text positions in the rest. That's why re.finditer isn't used. """ while m != None: """ The +/- 2 is because of the length of the " />'s. If not removed, the loop will run infintely! """ blip_text_view.DeleteRange(document.Range(m.start(1)-2, m.end(1)+2)) image = document.Image('http://www.forkosh.dreamhost.com/mathtex.cgi?' + m.group(1), caption=m.group(1)) blip_text_view.InsertElement(m.start(1)-2, image) m = latex_regex.search(blip_text_view.GetText()) if __name__ == '__main__': myRobot = robot.Robot('watexy', image_url='http://watexy.appspot.com/assets/icon.png', version='9', profile_url='http://watexy.appspot.com/') myRobot.RegisterHandler(events.WAVELET_SELF_ADDED, OnRobotAdded) myRobot.RegisterHandler(events.BLIP_SUBMITTED, OnBlipSubmitted) myRobot.Run()

