Using JRuby for DITA builds
By Eric Armstrong on Aug 15, 2007
There are serious advantages to using JRuby for DITA builds. I first wrote about the idea in Doing DITA Builds Better. That post mentioned Rake's advantage for sophisticated dependency detection, but didn't say much about how to achieve that goal. This one outlines a development progression. In the process, it hopefully elucidates the kinds of benefits that can be achieved.
Right now, I'm using the XDocs CMS system. XDocs puts a very nice wrapper around the Open Toolkit. That makes it possible to write a simple script in Groovy or JRuby that uses XDocs APIs to produce output. The engine itself tends to favor Groovy. But I'm thinking of JRuby, for the reasons detailed below.
The most notable advantage of using JRuby is the ability to modify the script to use Raven (the JRuby version
of Rake, which is the Ruby version of Make). Raven has the ability to invoke ANT tasks, which makes it a natural for work with the Open Toolkit. (Scripts in the Open Toolkit are really wrappers for ANT, which does all of the processing.)
The first version of the rake/raven script would be a simple, unconditional "do it". It would have exactly the same functionality as the script, only in makefile form.
The next step would be create a custom version of "task" (a method in Rake/Raven) that uses REXML (Ruby
XML parser) to look for topicref and conref targets. It would then add the targets as dependencies, to
minimize the number of things that are built. (In the previous post, I suggested the name dita_task. I'd love to find something shorter that's still semantically meaningful, but I have yet to stumble across anything better.)
That version also needs to include the variable values file ("variable map") as dependency. That's a feature that XDocs provides. (It may be based on standard DITA functionality, but I'm not sure.) Variable maps let you conref from a set of placeholders, and then substitute a set of values for those placeholders at production time. The "map" points to a file X and says, "substitute these values for any conrefs to file Y". The only proviso is that the files have the same ID, which you get by doing a Save As in your editor.
Those early cuts would simply include a ditaval file as a dependency. A later sophistication would parse the
ditaval value and ignore anything in the other files that are excluded.
The final, mega-sophisticated version might even be able to tell whether a conref target had changed, and
add the specfic content target as a dependency, rather than the whole file--but that's pretty far down the road,
and depends on sophisticated difference-detection in the CMS.