XML Syntax Highlighting with a Styled Text

Recently, I have been working on a stand-alone SWT application.

In this application, I had to provide syntax highlighting for XML documents. With SWT, the widget to use is called StyledText. A styled text widget requires a string to display and an array of style ranges. A style range defines a style (font, font size, font style), a starting index and a length. The idea is that the style will be applied between the start and start+length positions.

What was more difficult was to find a solution to determine the style ranges from a simple XML input. Such solutions exist for Swing, but I got nothing with SWT. There are solutions within Eclipse. But there are a lot of classes, a lot of dependencies and potential configurations. Basically, what I needed was a light lexical analyzer for XML. And I could not find it (which does not mean it does not exist). So, I wrote one myself.

Reinventing the wheel is always painful but sometimes necessary.

I saved my creation as a repository on GitHub: Xml Region Analyzer. There are two classes, that you can borrow and copy in your project (seriously, no need to create a Maven artifact for that).

It is very easy to use.

List<XmlRegion> regions = new XmlRegionAnalyzer().analyzeXml( yourXmlAsAString );

And from here, defining style ranges becomes easy.

/**
 * Computes style ranges from XML regions.
 * @param regions an ordered list of XML regions
 * @return an ordered list of style ranges for SWT styled text
 */
public static List<StyleRange> computeStyleRanges( List<XmlRegion> regions ) {

	List<StyleRange> styleRanges = new ArrayList<StyleRange> ();
	for( XmlRegion xr : regions ) {

		// The style itself depends on the region type
		// In this example, we use colors from the system
		StyleRange sr = new StyleRange();
		switch( xr.getXmlRegionType()) {
	        case MARKUP:
	        	sr.foreground = Display.getDefault().getSystemColor( SWT.COLOR_GREEN );
	        	sr.fontStyle = SWT.BOLD;
	        	break;

	        case ATTRIBUTE:
	        	sr.foreground = Display.getDefault().getSystemColor( SWT.COLOR_DARK_RED );
	        	break;

	        // And so on...
	        case ATTRIBUTE_VALUE: break;
	        case MARKUP_VALUE: break;
	        case COMMENT: break;
	        case INSTRUCTION: break;
	        case CDATA: break;
	        case WHITESPACE: break;
	        default: break;
		}

		// Define the position and limit
		sr.start = xr.getStart();
		sr.length = xr.getEnd() - xr.getStart();
		styleRanges.add( sr );
	}

	return styleRanges;
}

Anyway, this is not extraordinary but still efficient.
And since it may help others to gain some time in their projects, I shared it here.


About this entry