Tuesday, July 12, 2011

Contributing syntax highlighting in Orion

NOTE: The API described in this post is deprecated. Don't use it. Instead, check out this blog post at PlanetOrion, which explains a new & improved highlighting API.

I'm keeping this post around for reference only.

In this post, I'll explain how to write a plugin for Orion that contributes syntax highlighting for JSON files using a TextMate grammar. It will let us go from this:

…to this:

Which is much nicer on the eyes/brain.

What you need

An Orionhub account, or a build of Orion 0.2 running on your local server.

Language Grammars

Orion implements a subset of the language grammar format used by TextMate, a popular text editor for Mac OS X. A grammar gives a declarative description of the structure of files of a certain type (for example, a .java or .php file). This "structure" can be limited to simple keyword recognition using regular expressions, but the format provides enough power to recognize more complex language constructs like classes or function definitions. Sometimes a carefully-written grammar can even detect common syntax errors, such as a missing comma in a list of items.

The grammar provides rules that tell the underlying TextView what CSS class a portion of text should have. The mapping of CSS classes to rules (font-color, font-weight, etc.) is ultimately determined by the stylesheet applied to the TextView.

Finding a Grammar

We're going to use a JSON grammar, which its authors have made available under a BSD license. Not every grammar you come across in the wild will allow redistribution, so take note.

Download the JSON grammar file from here:

http://svn.textmate.org/trunk/Bundles/JSON.tmbundle/Syntaxes/JSON.tmLanguage

From PList to JavaScript

If you open the JSON.tmLanguage file you'll see that it's written in a strange XML dialect. It's actually a Property List file, which is a common data storage format used in OS X. TextMate's grammars are written as property lists. This poses a problem for all faithful JavaScript programmers, who avoid XML like the plague.

But don't whip out your validator just yet. It turns out that property lists convert fairly well to JavaScript object literals, and we've written a tool that will do it automatically:

Orion grammar converter

Running the converter

Go to the grammar converter in your web browser. Find the folder on your computer where you saved the JSON.tmLanguage and drag it onto the textarea shown in the converter. Immediately, the result should appear below it. Click the Clean up button and the converted JavaScript object will be formatted a little more nicely.

Copy and paste the JavaScript object from the text field into a new file somewhere. This is our grammar.

Packaging the Grammar as a Plugin

Now we have to write some code that registers our grammar with the Orion editor. Orion allows clients to contribute language grammars using the orion.edit.highlighter service.

First grab a copy of plugin.js, which provides the Orion plugin API. Put it in a new folder called JsonProject in your Orion workspace. In the same folder, create a new file called jsonPlugin.html with the following content:

<!DOCTYPE html> <html> <head> <title>JSON highlighting plugin</title> <script src="plugin.js"></script> <script> var jsonGrammar = /* Paste grammar object here -- omitted to save space */ ; window.onload = function() { var provider = new eclipse.PluginProvider(); provider.registerServiceProvider("orion.edit.highlighter", {}, { type: "grammar", fileTypes: ["json"], grammar: jsonGrammar }); provider.registerServiceProvider("orion.navigate.openWith", {}, { name: "Orion web editor", href: "/edit/edit.html#${Location}", validationProperties: {Name: "*.(json)"} }); provider.connect(); }; </script> </head> <body></body> </html>

The first registerServiceProvider call is the crucial part: it contributes our grammar and tells the Orion editor to use it for .json files.

The second registerServiceProvider call associates the Orion editor with .json files so you can click them from the Navigator view to open them in the editor. This is not strictly necessary to get syntax highlighting, but it's usually what you want when you're adding support for a new file type.

Installing and Testing

To install your plugin, you'll need to host it at a web URL. You can do this by launching the JsonProject folder as a standalone site from within Orion — see this page for instructions. Or if you have a personal web server, you can copy the project contents there instead.

Once you have a URL to jsonPlugin.html, visit the Plugins page in Orion. Type the URL into the box and click Install.

Reload the Navigator page so that the plugin we just installed takes effect. Create a new .json file. Click on it and the editor should open. At this point you should be able to see it recognizing JSON styling as you type:

Conclusion

We've seen how to take an existing .tmLanguage file and use it to provide syntax highlighting in Orion.

See Also