Home

Awesome

Leafdoc

Leafdoc (or 🍂doc for short) is a NaturalDocs- and JSdoc-like documentation generator.

Leafdoc's goals are to help produce documentation which is:

Try

See Leafdoc's own documentation as generated by Leafdoc, or the Leaflet documentation as generated by Leafdoc.

Try it yourself

git clone [...]
npm install
npm test

You will find a Leafdoc.html file. Open that file in a web browser, and you'll see Leafdoc's own documentation.

Command-line usage

npm install leafdoc
node_modules/.bin/leafdoc -t node_modules/leafdoc/templates/basic -o documentation.html src

See Leafdoc's own documentation for a reference of available parameters.

Write

The syntax is pretty much the tried-and-true directives-in-comment-blocks from JSdoc, NaturalDocs and a gazillion others. But instead of an @ symbol, Leafdoc uses a leaf:

/*
 * 🍂method addDir: this
 * 🍂param dirname: String
 * 🍂param extension: String
 *
 * Recursively scans a directory, and parses any files that match the given `extension`
 */

Leafdoc was designed with compactness in mind, so it accepts comment blocks consisting of adjacent // comment lines, and a shorthand syntax for function/method parameters. This is equivalent to the example just above:

// 🍂method addDir (dirname: String, extension: String): this
// Recursively scans a directory, and parses any files that match the given `extension`

If you need to be even more compact, use a semicolon (;) to put several directives in the same line:

// 🍂namespace Math; 🍂method sum(a: Int, b: Int): Int ; Returns the sum of two numbers

Valid directives

Shorthand syntax

Any documentable has the same syntax: name, optional required flag, optional parameters, optional type / return type/value, default value.

name[?] [ ( params ) ] [: type] [= default]

where params is

name[?] [ : type ]  [ , name[?] [ : type ]  [ , name[?] [ : type ] ...  ]   ]

and where name is a valid unicode identifier, or an ellipsis (). type and default are freeform and can have spaces.

Which means the following are possible:

An option usually has a type and a default value:
🍂option enabled: Boolean = true

But we can omit the default value:
🍂option enabled: Boolean

Or omit just the data type:
🍂option enabled = true

Or even just say there is an option:
🍂option enabled

A function with a return type:
🍂function get: String

A function with one parameter:
🍂function get(id: Int): String

Or two:
A function with one parameter:
🍂function sum(a: Int, b: Int): Int

The last function can also be written without the parameters shorthand:
🍂function sum: Int
🍂param a: Int
🍂param b: Int

Use an interrogation sign to specify a parameter as optional:
🍂function update(force? : Boolean): null

Use ellipsis to mark optional parameters:
🍂function update(…): null

You can specify everything (name, optional, params, type, default), but no documentable uses them all in the templates. The usual schema is:

ParamsTypeDefault
example
optionXX
propertyXX
eventX
methodXX
functionXX
factoryX
constructorX
factoryX

Relationships format

Relationships are meaningful for class diagrams. They correspond with the UML class diagram

The syntax is:

🍂relationship type namespace [ ,cardinalityFrom [ ,cardinalityTo [ ,label ]]]

The following relationship types are implemented for display in the graphviz-class-diagram templates:

Note that class inheritance is a separate directive (🍂inherits) .

namespace must be an identifier; cardinalityFrom and cardinalityTo must not have commas in them.

Some examples of how 🍂relationship works:

🍂namespace ConcreteClass
🍂relationship implements AbstractClass
🍂namespace Classroom
🍂relationship aggregationOf Student, 0..n, 1..n
🍂relationship aggregationOf Teacher, 1, 0..n
🍂namespace Caller
🍂relationship associated Callee ,, calls

Output customization

The output relies on a set of handlebars templates. By default, the ones in templates/basic will be used. In order to use another set of templates, pass the templateDir` option to the Leafdoc constructor, like so:

var l = new Leafdoc({templateDir: 'leaflet'});

I will write no detailed docs on how to modify the templates. If you know some HTML and handlebars, just copy them and hack things away :-)

Custom documentables

Your code might have several things of the same kind, which you want to show in the same fashion as documentables. Maybe it's files, or icons, or you have 5 trivial sub-classes which only merit one line.

You can define custom documentables by doing so:

var l = new Leafdoc();
l.registerDocumentable('icon', 'Available icons');

Whenever you add a custom documentable, you'll need to create its handlebars template too! Failure to do so will throw an error when you are building your documentation.

Your custom documentable will accept parameters, type, and default as the rest of documentables, and can follow the shorthand syntax. You will have to map parameters, type and default to something that makes sense for that documentable. For example, the template might map an icon's filename to the documentable's default:

🍂icon happy = 'icons/happy.gif'
A happy face

Also documentables can be inheritable or not. For example you have some entities in namespace which can be inherited. Pass true to third argument of registerDocumentable to make documentable inheritable:

var l = new Leafdoc();
l.registerDocumentable('field', 'Fields', true);

And later in your documentation:

🍂field limit? = 5
A limit for query

Known gotchas

Legalese

Licensed under the GNU General Public License version 3 (or "GPL3"). Check the full text at https://www.gnu.org/licenses/gpl-3.0.html.

Troubleshooting

I'm using Debian and I cannot see the leaf character!

Run apt-get install fonts-symbola.

I cannot type 🍂 in my keyboard!

(Linux only) Write this into a plain text file:

keycode  46 = l L l L U1F342 Lstroke lstroke

Then run xmodmap name-of-the-file. Now 🍂 is mapped to AltGr+l.

Of course, you can always do leafdoc.setLeadingCharacter('@');, but that's boring.