TeamCity uses JHighlight library to render the code on diff view page. Essentially what JHighlight is doing is it takes plain source code, recognizes the language by extension, parses it, and in case of success renders the HTML output where the tokens are highlighted according to the specified settings. Unfortunately JHighlight supports relatively small subset of languages out-of-the-box (major ones like Java, C++, XML, and several more). Here we'd like to present you a HOWTO on adding the support for more languages.
As an example we are implementing a highlighting for properties files, like this one:
The implementation consists of the following steps:
Step one: Writing a lexer using flex language
To understand this step you might need to familiarize yourself with a JFlex syntax.
There are several things you need to define in a flex file in order to generate a lexer. First of all, token types or, in our case, styles.
These constants will be mapped to the lexems in a source code and to the CSS classes, so at this moment you should decide which tokens are to be highlighted.
We will highlight names, values of properties, comments and plain text, which is just '=' character.
Then you need to specify the states and actual parsing rules:
Our simple lexer has two states: initial (YYINITIAL - it is predefined) and IN_VALUE. In each of these states we try to handle the next character (or a group of characters) using regexp rules.
The rules are applied from the top to the bottom, the first one that matches non-empty string is used. Each rule is associated with the action to be performed on runtime. Here we have only simple actions that return the token constant and sometimes change the state.
To end the composition of a lexer add the common part to be inserted to the Java file. It's unlikely that you need to modify it.
Here's the full result code:
That's it: the lexer is ready. Download the latest JHighlighter sources from the repository (version 1.0) and put this file to the
src/com/uwyn/jhighlight/highlighter directory of JHighlight distribution.
Step two: Generating a lexer on java
You can compile the code above using a JFlex tool, or amend the build.xml file adding the following task to the "flex" target:
After the compilation we'll have a java class PropertiesHighlighter implementing ExplicitStateHighlighter interface. If the previous steps are done right, you won't need to modify this file by hand.
Step three: The renderer class.
The only JHighlight class left is the renderer corresponding to the generated lexer. This class should extend a XhtmlRenderer class and provide CSS classes correspondence along with default CSS map:
You can leave DEFAULT_CSS empty, but in this case the styles should always be present in jhighlight.properties file. But it is essential that PropertiesHighlighter token constants are mapped to the CSS styles.
Also we need to tell the factory class that a new renderer exists: for this XhtmlRendererFactory class should be updated. We don't provide the code here as it is very simple (in fact, two lines should be added).
Step four: Running the JHighlight
JHighlight patch is ready, let's check it out in action. Put the properties file to the 'examples' directory and run the commands from JHighlight home directory:
Voilà! Our properties file is highlighted:
Including JHighlight Changes into TeamCity Distribution
TeamCity uses only public JHighlight API, that's why if your patched JHighlight successfully generates the HTML, you have to do just few steps to integrate it to TeamCity:
- restart TeamCity server