Utilizing docstrings

2019-06-19 01:51发布

It's a newbie question, but I didn't manage to google anything reasonably concise yet enlightening on the subject. I've got Sublime Text editor and an excellent plugin DocBlockr https://github.com/spadgos/sublime-jsdocs , which makes proper commenting a piece of cake. What am I supposed to do after I'm through with the comments? At a very minimum, I'd like to be able to invoke annotations in REPL. What else documentation wise is available? I want something lightweight and easy, for medium scripts.

EDIT:

var helper = exports.helper = (function() {

...

  /**
   * Reduces a sequence of names to initials.
   * @param  {String} name  Space Delimited sequence of names.
   * @param  {String} sep   A period separating the initials.
   * @param  {String} trail A period ending the initials.
   * @param  {String} hyph  A hypen separating double names.
   * @return {String}       Properly formatted initials.
   */
  function makeInits(name, sep, trail, hyph) {
    function splitBySpace(nm) {
      return nm.trim().split(/\s+/).map(function(x) {return x[0]}).join(sep).toUpperCase();
    }
    return name.split(hyph).map(splitBySpace).join(hyph) + trail;
  }
  /**
   * Reduces a sequence of names to initials.
   * @param  {String} name Space delimited sequence of names.
   * @return {String}      Properly formatted initials.
   */
  function makeInitials(name) {
    return makeInits(name, '.', '.', '-');
  }

...

})();

With $ jsdoc src.js no errors, but only dummy header is generated.

3条回答
我想做一个坏孩纸
2楼-- · 2019-06-19 02:19

When you write this

function bar (foo) {
    return foo + foo;
}

If you place your cursor in the line just above function and you write /** when you push « Enter » you'll be obtain this:

/**
 * [bar description]
 * @param  {[type]} foo [description]
 * @return {[type]}     [description]
 */
function bar (foo) {
    return foo + foo;
}

There are a lot of similary shortcurt.

For exemple, if you place your cursor after @param {[type]} foo [description], push « Enter » will create a new a * line, and write @ will propose you (in the intellisense) all JSDoc comments and the validation create a full line.

When your file is correctly documented, just use the jsdoc CLI to create your documentation.

Documentation: http://usejsdoc.org/

EDIT: I just realize the response to your question is in your https://github.com/spadgos/sublime-jsdocs link so maybe you want know how generate the documentation so...

Install Node.js and use CLI command

npm install jsdoc -g

Then, supposed file name you want document is foo.js, run the following command:

jsdoc foo.js

This will create a documentation into out directory.

All CLI documentation to generate doc is here : http://usejsdoc.org/about-commandline.html

查看更多
Rolldiameter
3楼-- · 2019-06-19 02:25

In your page: https://github.com/Tyrn/js-procr/blob/master/procr/pcn.js

You have the following line:

if (require.main !== module) return false;

That produce the following error: ERROR. Unable to parse xxx Line 291: Illegal return statement.

It's because no return is allowed in global scope so use this insteed:

if (require.main === module) {
    main.copyAlbum();
}

And all your documentation will be produced like a charm.

Actually, I don't know why your jsdoc command produce no errors in your environnent.

查看更多
放荡不羁爱自由
4楼-- · 2019-06-19 02:42

On Global

To allow JSDoc Template to generate your documentation, you have to add the @function attribute with the name of your function. Your two functions will appear in Global part of the template.

jsdoc your-exemple.js

But, because of your function are scoped in an anonymous function (but no module for moment), you do add the @private function to inform that function are not really global but just accessible in its scope. But, because by default JSDoc Generator Template ignore privates functions, add the --private options.

jsdoc your-exemple.js --private

So your code look like this.

(function () {
    "use strict";

    // ...

    /**
     * Reduces a sequence of names to initials.
     * @function makeInits
     * @private
     * @param  {String} name  Space Delimited sequence of names.
     * @param  {String} sep   A period separating the initials.
     * @param  {String} trail A period ending the initials.
     * @param  {String} hyph  A hypen separating double names.
     * @return {String}       Properly formatted initials.
     */
    function makeInits(name, sep, trail, hyph) {
        function splitBySpace(nm) {
            return nm.trim().split(/\s+/).map(function (x) { return x[0]; }).join(sep).toUpperCase();
        }
        return name.split(hyph).map(splitBySpace).join(hyph) + trail;
    }

    /**
     * Reduces a sequence of names to initials.
     * @function makeInitials
     * @private
     * @param  {String} name Space delimited sequence of names.
     * @return {String}      Properly formatted initials.
     */
    function makeInitials(name) {
        return makeInits(name, '.', '.', '-');
    }

    // ...

}());

Into Class

If you expose the content of anonymous closure to a variable var Helper, it's possibly a Class. So your code will not be a part of Global content but a part of Class with @class following by class name. And because you will provide your function towards the class module, you have no need to declare function as private.

But you do explain your previous function are part of the class so you have to use @memberOf with the full path to property.

  • Ending by . if it's a static member (exposed via return).
  • Ending by # if it's a method instanciable (exposed via this).
  • Ending by ~ if it's a private function not exposed at all (and @private).

So

/**
 * Helper Class
 * @Class Helper
 */
var Helper = (function () {
    "use strict";

    // ...

    /**
     * Split by Space
     * @function privateExemple
     * @private
     * @memberOf Helper~
     * @return {String}     ...
     */
    function privateExemple() {
        return "";
    }

    /**
     * Reduces a sequence of names to initials.
     * @function makeInits
     * @memberOf Helper.
     * @param  {String} name  Space Delimited sequence of names.
     * @param  {String} sep   A period separating the initials.
     * @param  {String} trail A period ending the initials.
     * @param  {String} hyph  A hypen separating double names.
     * @return {String}       Properly formatted initials.
     */
    function makeInits(name, sep, trail, hyph) {
        function splitBySpace(nm, sep) {
            return nm.trim().split(/\s+/).map(function (x) { return x[0]; }).join(sep).toUpperCase();
        }
        return name.split(hyph).map(splitBySpace).join(hyph) + trail;
    }

    /**
     * Reduces a sequence of names to initials.
     * @method makeInitials
     * @memberOf Helper#
     * @param  {String} name Space delimited sequence of names.
     * @return {String}      Properly formatted initials.
     */
    this.makeInitials = function makeInitials(name) {
        return makeInits(name, '.', '.', '-');
    }

    // ...

    return {
        makeInits: makeInits
    };
}());

Into Molule

But, in your case you use the exports so that mean your file is a module. So you have to describe this with @module and the name. So, all what you have previously comment will be not a part of Global but now a part of your Module. And because you will provide your function behind the Helper module, you have no need to declare function as private.

/**
 * Helper Module
 * @module Helper
 */
exports.helper = (function () {
    "use strict";

    // ...

    /**
     * Reduces a sequence of names to initials.
     * @function makeInits
     * @memberOf module:helper.
     * @param  {String} name  Space Delimited sequence of names.
     * @param  {String} sep   A period separating the initials.
     * @param  {String} trail A period ending the initials.
     * @param  {String} hyph  A hypen separating double names.
     * @return {String}       Properly formatted initials.
     */
    function makeInits(name, sep, trail, hyph) {
        function splitBySpace(nm) {
            return nm.trim().split(/\s+/).map(function (x) { return x[0]; }).join(sep).toUpperCase();
        }
        return name.split(hyph).map(splitBySpace).join(hyph) + trail;
    }

    /**
     * Reduces a sequence of names to initials.
     * @function makeInitials
     * @private
     * @memberOf module:helper~
     * @param  {String} name Space delimited sequence of names.
     * @return {String}      Properly formatted initials.
     */
    function makeInitials(name) {
        return makeInits(name, '.', '.', '-');
    }

    // ...

    return {
        makeInitials: makeInitials
    };
}());

Module and Class

But, because you expose via var Helper as a Class and via exports as a Module you could document in both way.

/**
 * Helper Class
 * @class Helper
 * @memberOf module:helper~
 * @see  {@link module:helper|Module}
 */
var Helper = (function () {
    "use strict";

    // ...

    /**
     * Reduces a sequence of names to initials.
     * @function makeInits
     * @memberOf module:helper.
     * @param  {String} name  Space Delimited sequence of names.
     * @param  {String} sep   A period separating the initials.
     * @param  {String} trail A period ending the initials.
     * @param  {String} hyph  A hypen separating double names.
     * @return {String}       Properly formatted initials.
     */
    function makeInits(name, sep, trail, hyph) {
        function splitBySpace(nm) {
            return nm.trim().split(/\s+/).map(function (x) { return x[0]; }).join(sep).toUpperCase();
        }
        return name.split(hyph).map(splitBySpace).join(hyph) + trail;
    }

    /**
     * Reduces a sequence of names to initials.
     * @function makeInitials
     * @private
     * @memberOf module:helper~
     * @param  {String} name Space delimited sequence of names.
     * @return {String}      Properly formatted initials.
     */
    function makeInitials(name) {
        return makeInits(name, '.', '.', '-');
    }

    // ...

    return {
        makeInitials: makeInitials
    };
}());

/**
 * helper Module
 * @module helper
 */
exports.helper = Helper;

Namespace or Class ?

The difference between a Class and a Namespace is just the Class expose some objects/functions via this and is instanciable. If nothing is attached to this, you have possibly a namespace so just replace @class by @namespace and that code will be placed into appropriate Namespace section.

You also check if your Class is not an Mixin (just used accross over Class but never directly) or an Interface (defined but not implement) if it an @extend of other class.

etc.

See the doc: http://usejsdoc.org/index.html

查看更多
登录 后发表回答