Manifesto
Download Demo
FAQs
Contact
  HomeSupport

Comparing DocJet to Doxygen, NDoc, and JavaDoc

Comparing documentation tools is difficult to do, mainly because while you are evaluating the tool, you spend most of your time configuring the tool to produce the sort of output you want. However, once you get to actually using the tool, you spend almost all of your time writing comments. Its this business of writing the comments that makes up the vast bulk of the cost of producing your documentation - whether you spend money on your documentation tool or not is neither here nor there. This page is dedicated to helping you understand the value that you get when you lay out money for DocJet.

Support

If you have a problem with a free tool, you can toss a question out to a message board and you may get an answer; then again, you might not, because nobody is getting paid to answer you. With DocJet, you'll get a definitive answer from someone who has been helping people document source code for a very long time.

With open source software, the answer to the question "Can I make it do X?" always boils down to "yes, but can I afford to spend the time?" DocJet is not open-source, but it bristles with published API's, source code examples and other ways to customize it, making it just as configurable as any open-source tool. Further, you can ask our support staff, "How can I make it do X?" and get a good starting point.  In most all cases, we are able to offer a very simple way to get you where you need to go. If it's more complicated and something that lots of people are likely to want, we might even do the work for you. If it's not something that would be generally useful, we can offer reasonable consulting rates.

Commenting style

All of the free tools require the comment-writer to adhere to an exacting commenting standard. The reasons have less to do with the markups being good as it is that the markups make it easy for the tool. Anytime you are talking about a free tool, you'll see compromises in usability being made in favor of the tool rather than the user. The reason is simple: free tools are written by the user; commercial tools are written for the user.

Both Doxygen and JavaDoc comments can be written with HTML markups in the comment. The appeal of this is that you can directly control the formatting of your output. Writing HTML markup in your comments can lead to subtle, but very thorny problems.   For instance, suppose we have this comment:

//  A return value of <B>TRUE<B> indicates that the
//  input value was acceptable; any other value indicates
//  an error.

Did you spot the error?  (Failing to use </B> at the end of the bold block). It is an easy mistake to make, and neither Doxygen or JavaDoc will detect it. The only way to find it is to browse through the documentation, and our experience is that in a production environment, that doesn't reliably happen. In most cases, your readers will report the error, not your coders. Given what we all know about the cost of fixing a problem increasing with the time it takes to detect it, this trivial little problem can easily become quite expensive to fix in addition to being embarrassing.

The second problem with this comment revolves around the issue of why we bolded "TRUE" at all. Might it be the case that we really want to bold all instances of "TRUE" and "FALSE"?  Essentially we're creating a meta-class here, and so the correct way to denote it would be <SPAN CLASS=BoolConstants>TRUE</SPAN>.

That leads us to NDoc's commenting style, which is based on XML. Were we faced with this issue in code maintained with NDoc, we might create a new markup, <true>, and write this, instead:

//  A return value of <true/> indicates that the...

That way, every time we wanted to create a properly decorated "TRUE", we would just use that markup. This is quite an improvement in correctness over plain HTML, but it does impose a certain amount of overhead (you have to create the markup) and requires some discipline (you have to make sure that each time you want to use "TRUE", you write "<true/>" instead.

Both Doxygen and JavaDoc define their own comment markups, in conjunction with HTML markups. NDoc does the same sorts of things, but since it uses XML as a starting point, no new syntax need be invented - just more XML markups.

For compatibility's sake, DocJet can parse JavaDoc and XML comments, but that's not really the best way to use DocJet.

A Better Way

When you buy a tool, you expect it to serve your needs, and that's what DocJet is about. It has an amazingly sophisticated heuristically-driven natural-language comment parsing engine. For example, if you give it something like this:

//  Return Value:
//   0           The operation completed successfully
//   E_NOTFOUND  The requested object was not found
//   E_INVAL     The argument was invalid (null pointer)

The DocJet parser would first see "Return Value:" and know that what followed described what the function/method returns, and then see the rest and notice, based on the spacing and capitalization that the rest of the text was a table. Further, since this table was the sole contents of the return value section of the comment, that distinguishes this table from other tables that might be found elsewhere in the comment. So, in the output, this whole affair would be built into a neatly formatted HTML table complete with appropriate column headers.

This table can be expressed with markup, of course, and the adherents of markup in comments will say that the markup makes it more precise. But take a look at that comment!  The writer has clearly and unambiguously defined how he wants the information presented; any programmer could look at that comment and instantly grasp the intent. That's because we humans have implicitly written a markup language for ASCII formatting which we humans find easy to parse. Instead of symbols like "<", "/" and ">", this markup language uses spaces and newlines.

The argument that a comment composed of HTML markup is better than one written in plain text holds no water. Comments don't just serve the documentation generator - they also serve their traditional role of helping people who are maintaining the code. Thus it's just as important for comments to be readable in the code as it is for comments to be readable in the output. With markup, comments become far less readable, and thus far less valuable to the code maintainer. Moreover, writing the comment with markups requires a great deal more effort. Realistically, with this additional workload, most coders will change the above comment to "0 on success, else the result is an error code."

The bottom line is this: It's one thing to define a strong commenting convention with nice neat markups and style guidelines, but it's quite another to see it properly implemented. If you make it hard for programmers to write comments, they simply won't write them. If, on the other hand, you give them broad latitude in terms of style and content and just tell them to focus on writing a good description of what the program does, they are much more likely to give you good content.

It's that observation that drove the design of DocJet's comment-recognition system. Instead of programmers struggling to meet a standard set forth the commenting tool, DocJet adapts to the commenting style of the programmer.

Documenting the Obvious

On the surface, a comment documenter tool is a pretty simple thing.  It's just a matter of finding objects, rearranging the comment to match the output format, and generating the output. That's what the free tools do, and it works, to the extent that humans do a good job of writing comments.

It's this last part where things get interesting. Do you own a hammer?  Notice how that the hammer's head is about 1" in diameter. The physics of the tool are such that the hammer would work as well or better if the head were smaller. If you're like most of us, you bang your finger plenty often enough with the 1" diameter, so while a smaller hammer head might look good on the drawing board, it would not work well in practice. Software tools, like woodworking tools, cannot be called good or bad based on the tool by itself - you need to look at the total system, the tool plus the human that uses it.

Take a look at these two constructors:

// Default constructor
CFoo::CFoo()
{...}
CBar::CBar()
{...}

Would you say that CFoo's constructor is documented and CBar's is not?  Yes, CFoo does have a comment in front of it, but the comment doesn't say anything that isn't immediately obvious from the declaration. For all practical purposes, CFoo and CBar are both equally well commented and the author of CFoo did a bit of extra work in throwing in the comment.

DocJet understands the code it's documenting a great deal better than NDoc, Doxygen or JavaDoc, and, as a result, one of the things it's able to do is supply comments for obvious cases like what we have above. If you submit that code to DocJet, it would fill in the blank on CBar::CBar, producing documentation that is essentially the same as that for the commented CFoo.

Let's increase our sophistication a bit and move on to the copy constructor:

CFoo::CFoo( const CFoo &c )
{...}

Suppose you were a programmer on a documentation binge and came across that dude. In the absence of DocJet's automatic commenting, almost all programmers would either type in "// Copy constructor" or cut & paste the comment from another copy constructor into this spot.  Programmers know a downhill road when they see one.

However, if you were commenting along and ran across this and you knew that a reasonable default will be provided for you, you could either (1) skip the comment altogether, or (2) provide more detail. For instance, in DocJet, if you supplied:

// This makes a deep copy of c.
CFoo::CFoo( const CFoo &c )
{...}

Your comment, regarding the deep vs. shallow copy, would become the "Remarks" in the output and the default copy constructor brief description would be used as well. To put it another way, writing that, above, would be as good as writing this, in NDoc:

// <description>This creates a new instance of the object.</description>
// <remarks>This makes a deep copy of c.</remarks>
CFoo::CFoo( const CFoo &c )
{...}

Again, what DocJet is doing here goes beyond code. It's goal is to provide an environment where the easy thing for the programmer to do is also the best thing a programmer can do. When faced with the constructor, the programmer is asked to think, "Is there anything that is special about this particular copy constructor?"  If so, you can supply a comment that specifically talks about that. If not, fine, move on to another object where you do have something important to say.

The Perils of Commenting by Cut&Paste

So far, we really have been talking about how DocJet helps you document the rare cases that were pretty easy to document to begin with. So now let's take it up another notch into the world of inherited methods:

interface IFoo {
  // <extensive comment>
  void frob();
};

class CFoo implements IFoo {
  void frob();
};

DocJet employs the notion of inherited comments as well as the automatic comments we discussed before. In this case, any comment you put in front of CFoo::frob would override and complement IFoo::frob in much the same way as we discussed before for DocJet's notion of automatic commenting. For just about any reasonable case, the root method defines the purpose and interface of a method. That is, in IFoo::frob, you would talk about what the inputs are, what the effects are, and what the output is. In CFoo::frob, all that would continue to be the same; all you have to add there is any comments on how the class implements the method. In most cases, there's no need to put any comment at all on CFoo's frob method, because, in most cases, the reader of the documentation really doesn't care how CFoo implements frob.

Now that we have talked about the advantages of inherited documentation, let's talk about what happens in its absence. In that event, given the mandate to "document" all the code, how would a programmer react to seeing this bit:

void CFoo::frob();
{
...

In most cases, a programmer will "document" the above code by cutting&pasting the extensive comment from IFoo. That certainly works for the first go at documentation, but what happens later when someone updates the interface to IFoo::frob?  Only the most determined optimist would expect that the comment for CFoo::frob will get updated to reflect the change.

Organization and supporting documents

Just for a moment, let's pick on Microsoft. Consider this page from the .Net Framework SDK:

These are the comments that try men's souls. There's almost nothing on this page that you couldn't have gleaned from the declaration.  When do changes to this property actually display on the screen?  Do you need to redraw?  What do they mean by "ambient"?  What exactly constitutes the "background"?  One would hope that the root class, AmbientProperties, would tell us what ambient properties are, but no, it really doesn't. We might hope that the link to BackColor will yield answers to the issue of what constitutes "background", but that turns out not to be the case either. The reality is that we have an object with a page full of "documentation" that says absolutely nothing.

It's easy to blame the writer of this comment for its shortcomings, but put yourself in their shoes. What would you write?  It wouldn't be appropriate to discuss background colors here, would it?  Not in the code, no; the notion of "background" is wider than one or two properties. Similarly for ambient properties - you couldn't properly discuss ambient properties without contrasting them with primary properties.

People don't set out to write comments like poor BackColor here, they just end up doing it when the documentation tool they are using doesn't offer them an alternative. The real shortcomings here are those of the tool, not the author. Neither NDoc nor JavaDoc provide any meaningful way to integrate externally-written documents into the documentation-set.  Further, they have no means of controlling what the table of contents looks like - they just dump the objects out by a combination of code-structure and alphabetical order.

Doxygen, much to its credit, does allow for that, but not to the extent nor sophistication of DocJet. With Doxygen, you can create an overview topic either in the source file or in a separate file. Those methods are supported by DocJet; in addition, you can use a GUI-based tool for editing overview topics, glossary terms and other such supporting documentation.  Also, with DocJet, you can bring in documents written on a Word Processor and integrate those into the output set.

Here's a typical screenshot of DocJet's tool for creating and managing your documentation's table of contents:

Having a visual tool like this makes it far easier to see the organizational structure of your code. You can either totally control how your objects are laid out in the table of contents using the graphical interface here, or you can use a wide variety of means to organize them from the code.

Once again, the advantages to a tool like this are more sociological than technical. Producing documentation is a team effort, involving coders, writers and their managers. It's here that the manager of the documentation product merges the work of the coders with documents produced by technical writers to form the total organization of the document. With DocJet, all the members of the documentation team work with tools and methods that are familiar to them.

Summary

When selecting a code commenting tool, it's crucial to understand this fact: no matter how good the tool is, it will produce garbage unless the programmers write good comments. By "good comment", we mean that it says something meaningful about the object being described; whether it's a syntactic tour-de-force or not is irrelevant.

Complicated markup requirements discourage the writing of comments, that's why DocJet uses a freeform style of comment input. Of course, some people just feel more comfortable with markup, so DocJet can do that too.  Whatever makes the comment-writer happy is good with DocJet.

Programmers, like most people, are positively motivated by the thought of producing a top-quality product. By allowing for the integration of external documents and a table of contents, you don't have to shoehorn the subject matter into one comment or another - you can write comments that talk about just the object, and, if needed easily refer to other documents that describe the broader concepts.