Friday, April 24, 2009

JavaFX Brush for SyntaxHighlighter

I wanted to display well-formatted JavaFX Script source code using Alex Gorbatchev's SyntaxHighlighter. But the current version of SyntaxHighlighter does not include a JavaFX brush. So I wrote one. A sample of highlighted code is below. Note that some of the code is a bit silly. It is written that way to exemplify the highlighting features.
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.Scene;
import javafx.scene.shape.Circle;
import javafx.scene.transform.Scale;
import javafx.stage.Stage;

/**
 * @author Patrick Webster
 */
var mouseX: Number;
var mouseY: Number;
var scale: Float = (-2.3 - 1.0) * -1.;
var egg: Circle;

Stage {
   title: "Easing Raw Egg"
   scene: Scene {
      fill: Color.BLACK
      height: 0x2EB  width: 0X30C
      content:
         egg = Circle {
            fill: Color.WHITE
            centerX: bind mouseX
            centerY: bind mouseY
            radius: 323.456e-02
            transforms: Scale {
               // Egg eases to moving mouse cursor
               pivotX: bind mouseX
               pivotY: bind mouseY
               x: bind scale * .02298E3
               y: bind scale *  32.56789
            }

            onMouseMoved: function( me: MouseEvent ) {
               updateMousePosition(me);
            }
            onMouseWheelMoved: function( we: MouseEvent ) {
               updateMousePosition(we);
               updateScale(we);
            }
         }
   }
}

function updateMousePosition(me : MouseEvent) : Void {
   mouseX = me.x;
   mouseY = me.y;
}

function updateScale(we: MouseEvent) : Float {
   var newScale = scale + (we.wheelRotation * -0.1);
   if (newScale < 1.0)
      return scale = 1.0000000e+00;
   return scale = newScale;
}

There are others who have written JavaFX brushes for SyntaxHighlighter, but they all lack the functionality that I desire. My implementation differs from others by including these additional features:
  1. Negative signs for constants are highlighted.
  2. Constants with scientific notation are highlighted.
  3. Leading and trailing decimal points are highlighted.
  4. Keywords are up-to-date for JavaFX 1.1.1.
  5. Deprecated keywords are supported.
  6. JavaFX built-in data types are highlighted differently than keywords.


Constants
In order to recognize all number formats for constants in JavaFX Script, I wrote the following horrendous regular expression:
/(-?\.?)(\b(\d*\.?\d+|\d+\.?\d*)(e[+-]?\d+)?|0x[a-f\d]+)\b\.?/gi
I am not going to explain every little detail of the above mess, but I will say that there are basically three parts. The first part matches on regular numbers with an optional leading negative sign and decimal point. The middle part looks for scientific notation. The last part checks for hexadecimal format. The major assumption is that correct JavaFX Script is the input. It is possible for the above expression to match on illegal code, but the hope is that people will not be highlighting incorrect code on their blogs. One small problem is that the above regular expression will match on the binary subtraction operator if there is no space between the operator and the subtrahend:
def b: Double = a-4;
I would prefer if the minus operator were not highlighted. But in general, it is good style to surround binary operators with a space, so this is really not a big problem.


Keywords
As the JavaFX Script language evolves, keywords come and go. The latest JavaFX Script 1.1.1 keywords are listed here. I'm sure this list will need to be updated again after the next language revision. I also include a separate list of deprecated keywords that is easily commented-out if desired.


Built-In Types
There are several built-in data types in JavaFX Script. I chose to highlight the following types in their own distinct color:
Boolean Byte Character Double Duration Float Integer Long Number Short String Void


Blogger Usage
If you followed my instructions on how to install SyntaxHighlighter into Blogger, then getting the JavaFX highlighter working will be a simple task. First you will need to download my brush file here. Expand it and place it somewhere on the internet. Then insert a link to the brush file in your Blogger HTML template. For example, I inserted this line in my template:
<script src='http://patrickwebster.googlepages.com/shBrushJavaFX.js' type='text/javascript'/>
I do not recommend that you link to my file because the file may move or change names at any time. Once the template is edited, new JavaFX code can be highlighted by wrapping it in the <pre class="brush: javafx"> and </pre> tags. The brush aliases 'jfx' or 'javafx' may be used within the <pre> tag.


Update: May 3rd, 2009
The newly released version 2.0.320 of SyntaxHighlighter includes a JavaFX brush! So you do not need to download my script. Simply upgrade to the new release and wrap your JavaFX code in the <pre> tag as explained above. You can link to the hosted version of the brush file by adding the following line to the appropriate section of your Blogger template:
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJavaFX.js' type='text/javascript'/>