Hire Me! I'm currently looking for my next role in developer relations and advocacy. If you've got an open role and think I'd be a fit, please reach out. You can also find me on LinkedIn.

A long, long time ago, ok, it was last Thursday, I posted about adding Markdown processing to BoxLang via the Flexmark Java library. After posting it, a few folks were curious why I didn't use the native import process instead of createObject('java', '...') and the answer was simple - I just didn't think about it! To give you an idea of the difference, let's first consider the initial version:

function markdownToHTML(str) {

	// .init() is important!
	ds = createObject("java", "com.vladsch.flexmark.util.data.MutableDataSet","flexmark-all-0.64.8-lib.jar").init();
	ps = createObject("java", "com.vladsch.flexmark.parser.Parser","flexmark-all-0.64.8-lib.jar").builder(ds).build();
	hm = createObject("java", "com.vladsch.flexmark.html.HtmlRenderer","flexmark-all-0.64.8-lib.jar").builder(ds).build();
	
	doc = ps.parse(str);
	return hm.render(doc);
}

In this version, I use createObject for my three Java objects to get to the final result I need, an HtmlRenderer object I can pass a parsed string to. Now consider this version:

import com.vladsch.flexmark.util.data.MutableDataSet;
import com.vladsch.flexmark.parser.Parser;
import com.vladsch.flexmark.html.HtmlRenderer;

function markdownToHTML(str) {

	ds = new MutableDataSet();
	ps = Parser.builder(ds).build();
	hm = HtmlRenderer.builder(ds).build();	

	doc = ps.parse(str);
	return hm.render(doc);
}

This version is a heck of a lot simpler in terms of what's being done. Technically the imports there break encapsulation from the simple UDF I had written, but I would have used a class in a real application anyway.

There is one small issue with this version and that's finding the Jar. If you remember, with createObject I can point to the jar, so what do I do here?

If I'm running this in a web application, I'd just use javaSettings to specify it there. Outside of that, for right now there isn't a simple one liner BIF (built-in function) with similar functionality, but we can hack it up like so:

import com.vladsch.flexmark.util.data.MutableDataSet;
import com.vladsch.flexmark.parser.Parser;
import com.vladsch.flexmark.html.HtmlRenderer;

bx:application name="myJavaApp" javaSettings={
  loadPaths = [ expandPath( 'flexmark-all-0.64.8-lib.jar' ) ]
};

function markdownToHTML(str) {

	ds = new MutableDataSet();
	ps = Parser.builder(ds).build();
	hm = HtmlRenderer.builder(ds).build();	

	doc = ps.parse(str);
	return hm.render(doc);

}

The bx:application component essentially turns my script into a web application (for the execution of the template) and can therefore make use of javaSettings. As I said, a bit of a hack, but honestly, for CLI scripts I'm fine with that, and, there's an open issue in the BoxLang Jira to add a proper BIF for this.

You can find this version in our bx-demos repo here: https://github.com/ortus-boxlang/bx-demos/blob/master/java-interop/flexmark2.bxs

Obviously, both versions work, and it comes down to which style you prefer in your code base, but it's a good example of the flexibility in BoxLang!