Tricking out Ruby Documentation: Picking the Right Documentation Generator Tool
In my other blog, I recently wrote a post about the characteristics of a good software documentation creation and publishing pipeline. A documentation generator is the core of such a pipeline. Designing Patterns has written several open-source Ruby gems, and in order to create a documentation pipeline for these, I evaluated the documentation generators for Ruby. I think that RDoc is the best such tool.
I previously have used Javadoc and Doxygen, but neither supports Ruby. There are multi-language tools that understand Ruby code in a basic way, such as Natural Docs and ROBODoc, but none that offers strong support for the language’s features and idioms. RDoc is the standard documentation generator used within the Ruby community. Like Doxygen, it can parse source code and, even without any comments, generate web pages documenting the code. It has a number of very impressive strengths:
- It has very strong support for Ruby syntax and idioms, including being able to document attributes, methods that accept blocks, and metaprogramming constructs.
- It provides a very natural markup language that can be written and read easily, even as plain text.
- It has a powerful cross-referencing engine that automatically generates class and method cross-reference links in the text of the web pages that it produces.
- It inlines or links to a method’s source code in the HTML documentation that it generates for the method.
- Using graphviz, it can embed class diagrams into the web pages that it generates.
- It can generate several different formats of documents, including HTML, XML, texinfo (which in turn can be used to create PDF documents), and Windows Help.
- It includes ri, the standard Ruby tool for viewing documentation on the command-line, and can generate documentation for ri.
- It can parse C code and understands the C/Ruby calling conventions, so it can generate documentation for classes written in both C and Ruby.
- It uses a powerful templating system based on embedded Ruby to generate HTML, allowing developers to create new templates in order to customize the look of their web documentation.
- There is tremendous support for it in the standard Ruby tools; the gem system, rake, and hoe use it to generate documentation.
Unfortunately, RDoc has some significant weaknesses, including:
- Its markup language is not very expressive; in particular, there is no descriptive markup for programming elements, like method parameters and return values. Both Doxygen and Javadoc offer such markup. At Designing Patterns, we compensate for this to some extent by using an emacs macro to generate markup that simulates descriptive markup for programming elements (see this method documentation for example).
- The web pages produced by the default HTML template look pretty poor. This is an example, generated for Ruby’s Core Library. It looks dated and, worse, the frames at the top make reading the pages difficult. I always find myself making the top frames taller in order to see more of the class, file, and method lists but then later making the top frames shorter in order to see more text in the central frame. At Designing Patterns, we use a beautiful 3rd party template, Hanna, to produce documentation like this.
- Although Ruby’s standard tools support RDoc, they often offer limited ability to specify RDoc options, such as which HTML template to use. I fixed this to some extent with a patch that allows one to specify RDoc options through the
RDOCOPTenvironment variable, similar to how theRUBYOPTenvironment variable allows one to specify options for the Ruby interpreter.
RDoc has many strengths, and its flaws, while significant, can be compensated for well enough to make it very suitable for our company’s purposes. Its maturity, the support for it in the standard Ruby tools, and its widespread adoption by the Ruby community make it particularly attractive for use in a production toolchain. While designing a documentation pipeline around it, I have submitted a number of patches and lately have become an RDoc developer. Active development recently has been restarted, and so I have no doubt that its flaws will be fixed and that it will continue to improve in future releases.
There are two other documentation generator tools for Ruby. The first is RDtool. This was used heavily prior to RDoc, but, unlike RDoc and Doxygen, it does not generate documentation for classes and methods automatically. In fact, it is not a source code documentation generator at all but is instead a more general formatting tool; this discusses the differences between RDTool and RDoc in greater depth. RDTool’s lack of support for source code means that much more formatting is required in order to create proper documentation, and so I immediately rejected using it. The other alternative is Yard (also called Yardoc). This is a relatively recent tool in the vein of Doxygen and RDoc. It offers the following advantages over RDoc:
- It provides descriptive markup for programming elements, very similar to that provided by Doxygen and Javadoc.
- It offers an API to customize the parsing of source files, allowing it to accommodate new metaprogramming constructs easily.
- In a class’ documentation, it shows methods inherited from a parent class.
- The default look of its generated web pages is better than RDoc’s.
Yard, however, has the following disadvantages:
- It is not very mature. In fact, the version that I tried crashed on one of my gems.
- It cannot parse C code, and so it can not create documentation for the Ruby Core Library or for gems written in C and Ruby.
- There is no built-in support for it in the standard Ruby tools.
- It only provides built-in support for generating HTML, although it was written to allow the addition of other output formats with relative ease.
Given the above Yard vs. RDoc points, I think that RDoc is the better choice for Designing Patterns as Yard does not seem ready for our production use. It does, however, have a number of interesting and exciting features. I hope that the two tools will cross-pollinate and even share code in the future.
In forthcoming posts, I will discuss how to create a documentation pipeline around RDoc that utilizes its strengths and masks its weaknesses.
You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.
Leave a Reply