Ionică Bizău

Increasing productivity using Blah 2.0.0

Few months ago I was introducing Blah–one of nicest tools I ever used in module/project development. It helped me a lot. Literally. More than 80% of my projects documentation was generated by this tool.

Recently I started building some new features, working on the 2.0.0 milestone of this project and finally, the 2.0.0 branch was merged. 97 commits, 34 files changed, and 1.659 lines changed (1,197 additions, 462 deletions). Cool, right? Let's see what's hiding behind these numbers.

Blah Help


The new big feature is templates. There are three levels of Blah templates:

  • project templates
  • user templates (located in ~/.blah-templates)
  • default templates (located in the Blah core)

You can read the pull request description if you want to find more technical details. Next, I will present a simple example how to use Blah 2.0.0 or how to automagically not waste your precious time for writing docs.

Installation

Thanks to npm, the installation is easy:

$ npm i -g blah

If this command requires root access, make sure you configured NPM correctly. Using sudo npm i -g blah is not a big issue, anyway.

Creating a project

When starting a project, I create the file structure which looks like below:

$ tree
.
├── example
│   └── index.js
├── lib
│   └── index.js
└── test
    └── index.js

3 directories, 3 files

To create such a thing, do:

$ mkdir hello-blah && cd hello-blah
$ mkdir example lib test
$ touch example/index.js lib/index.js test/index.js
$ git init # if you want to have it as git repo

Starting writing code

I always like to start by writing the example. In this case, let's make a library to display Hello World!

So, I do:

// Require the library file
var HelloBlah = require("../lib");

// Call the function exported by library
HelloBlah();
HelloBlah("Blah");

Obviously, node example/ will fail, because object is not a function–in other words, we didn't export anything in the library file (lib/index.js).

Now we have to write the library file:

/**
* HelloBlah
* Displays and returns a *Hello <world>!* message.
*
* @name HelloBlah
* @function
* @param {String} world The world you want to say *Hello* to (default: `"World"`).
* @return {String} The *Hello <world>!* message.
*/
function HelloBlah(world) {
    world = world || "World";
    var message = "Hello " + world + "!";
    console.log(message);
    return message;
}

module.exports = HelloBlah;

I used jsDoc comments that will help when generating documentation.

Now, since we exported the library function, our tiny example works fine:

$ node example/
Hello World!
Hello Blah!

There is one step before generating the documentation using Blah. Having a package.json file (which is used to publish the library on npm registry) helps Blah:

{
  "name": "blah-test",
  "version": "1.0.0",
  "description": "Testing the new version of blah.",
  "main": "lib/index.js",
  "directories": {
    "example": "example",
    "test": "test"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Ionică Bizău <[email protected]> (http://ionicabizau.net)",
  "license": "MIT"
}

`

This can be generated using npm init. As you probably noticed, I don't have time to write the tests for this library since it's not the main point of this article.

Using Blah to generate the docs

And now the most exciting part! You have a working library–small, cute, but not awesome enough without documentation. Blah does that for you.

Just run the following command and let the magic happen.

$ blah -c -g -r -l MIT -d lib/index.js

And now what? Blah generated the following files:

  • CONTRIBUTING.md (blah -c or blah --contributing)
  • .gitignore (blah -g or blah --gitignore)
  • README.md (blah -r or blah --readme)
  • LICENSE (blah -l <license-name>)
  • DOCUMENTATION.md (`blah -d path/to/file.js)

And one more point: because it is smart enough, it put your information in the LICENSE file.

Using Blah templates

Most probably Blah used the default templates, in your case. The default templates are a set of defaults that (hopefully) everyone can agree on. Well, I don't. Since I maintain a bunch of projects, I want to have my own documentation format, adding some custom stuff to the default templates.

The Blah templates are written in EJS. Since it EJS lets us to run custom JavaScript code, it's very easy to write our custom stuff. For example I extended the package.json file with the following fields:

{
    "blah": {
        "h_img": "http://example.com/heading-image",
        "ex_img": "http://example.com/example-image"
    }
}

I don't always use it, but sometimes I do. That's why I copied the default template into ~/.blah-templates/README.ejs and added at the top of the file the following snippet:

<% if (_.pack.blah.h_img) { %>
![<%- _.pack.name %>](<%- _.pack.blah.h_img %>)
<% } %>

That means: if there is a heading image render it, otherwise do nothing.

If you want to see my customized templates, check out my dotfiles.

I published this example of using Blah here.

Project templates

But sometimes these user-level templates are not enough–maybe you want to have some custom stuff inside of your project and not pollute your other projects with that.

Well, you need project-level templates. Blah does that for you. Run blah -i to initialize the .blah directory in your project. If you have user-level templates, they will be copied in the .blah directory, otherwise the defaults will be copied.

Then, next time when you generate documentation with Blah, these templates will be used.


Finally, keep this in mind: generate documentation. It's easier, faster, better, cooler. Let Blah do that for you. Don't waste your time.

Like always, don't forget to check out the Blah project repository and open issues for anything (questions, bugs, features, discussions etc). Contributions are also welcome!

Happy Blahing!

Have feedback on this article? Let @IonicaBizau know on Twitter.

Have any questions? Feel free to ping me on Twitter.