List of JSDoc3 Plugins

2,860 views
Skip to first unread message

mathematical.coffee

unread,
Nov 21, 2012, 1:07:55 AM11/21/12
to jsdoc...@googlegroups.com
I thought it would be a good idea for there to be a central place for people to list JSDoc plugins they've made and are happy for others to use - that way if we as users are after a quick fix/feature, we can browse through the list of plugins and see if any of them help us.

I'm unsure if such a resource exists already, so I thought I'd start a topic for it. Although I think this would work nicer on a wiki page or something.

(As an aside - for those of you who use version management, how do you store your plugins? do you fork jsdoc and just commit the entire repo with all your plugins, or do you make a separate repository per plugin?)


To get the ball rolling, I thought I'd add a couple of plugins I've been muddling along with.

First, a disclaimer - the plugins I've shared appear to work for my documentation, but are not widely tested so don't be surprised by things that don't work! If you like you can email me if you notice something not working (preferably with a fix :P) and I can incorporate it, but I don't intend to do full support of the plugins - they're really for my personal use and I share them in case they might help others. Feel free to tweak them to your uses.

pragmaTag
Status: Appears to be working, not rigorously tested, subject to further development/changes.
Description:
adds two tags, `@+` and `@-`. Tags added in the '@+' will be added to subsequent doclets until '@-' is encountered. Can be nested. NOTE: for the moment "subsequent doclets" means only those that have associated symbols, i.e. it excludes virtual doclets documented with @name and so on. I don't know how to get it working for those yet.
Known issues:
* only doclets that have a corresponding bit of code will be affected by the @+ and @-. In particular, virtual doclets that are not associated with code such as blocks using `@name` will not be affected. This is because of issue #228 (I think this can be worked around but I haven't figured it out yet)

Example:
// example: use of pragma tags for lots of constants
// Let's document the following code:
const MY_CONSTANT = 1;
const MY_CONSTANT2 = 2;
const MY_CONSTANT3 = 3;
const MY_CONSTANT4 = 4;

// ------ without pragma tags ------ // ------ with pragma tags ------ //
/** Some documentation               // /** @+
 * @const                            //  * @const
 * @default                          //  * @default
 * @type {number} */                 //  * @type {number} */
const MY_CONSTANT = 1;               //
                                     // /** Some documentation */
/** Some documentation               // const MY_CONSTANT = 1;
 * @const                            //
 * @default                          // /** Some documentation */
 * @type {number} */                 // const MY_CONSTANT2 = 2;
const MY_CONSTANT2 = 2;              //
                                     // /** Some documentation */
/** Some documentation               // const MY_CONSTANT3 = 3;
 * @const                            //
 * @default                          // /** Some documentation */
 * @type {number} */                 // const MY_CONSTANT4 = 4;
const MY_CONSTANT3 = 3;              //
                                     // /** @- */
/** Some documentation               //
 * @const                            //
 * @default                          //
 * @type {number} */                 //
const MY_CONSTANT4 = 4;              //


inheritDoc
Status: Appears to be working (again, might not stand up under rigorous use or use outside of my documentation setup)
Description:
Added tags:
  • @inheritparams <someOtherSymbol>: copies the parameters and return values of <someOtherSymbol> to the current doclet. They can be overidden.
  • @inheritdoc <someOtherSymbol>: as above, but additionally copies the description, summary, classdesc (where they have not been specified).
  • @override: the same as @inheritdoc, but use it in a subclass method that overrides the superclass method and you then don't have to write <someOtherSymbol>.
Known issues:
  • I think Google/Java Closure Compiler also has @override and @inheritdoc, and I suspect mine does something different to theirs, so make sure you understand what each tag does before using it (you may wish to modify the plugin and rename the tags to something less confusing if you like; for me I have never used any other documentation system with these tags so it doesn't bother me)
  • I have no idea what happens if you daisy chain many @inheritdoc/@inheritparam in various orders (within the file). I'd like to hope that things work, but don't be surprised if many nested levels of @inherit... fail on some parameters.
Example:

/** a function                                                                  
 * @param {number} x - x value                                                  
 * @param {number} y - y value                                                  
 * @returns {number} a number
 */                                                                             
function myFunction (x, y) {                                                    
    return x + y;                                                               
}                                                                               
                                                                                
// x, returns and description ("a function") documentation are taken from myFunction
// y should be overridden, z should be there.                
/**                                                                             
 * @param {number} y - overridden y explanation                                 
 * @param {number} z - z value                                                  
 * @inheritdoc myFunction                                                       
 */                                                                             
function myFunction2 (x, y, z) {                                                
    return x + y + z                                                            
}                                                                               
                                                                                
// only y is borrowed from myFunction as myFunction has x and y only
// if you document z explicitly it will be there, otherwise it will show up as "undocumented"
/** another function
 * @inheritparams myFunction                                                    
 * @returns {number} fasdf                                                      
 */                                                                             
function myFunction3 (y, z) {                                                   
    return y + z;                                                               
}


I hope others add their plugins here so we get a nice plugins list going! (Note - if you're looking around in the repo that those plugin files came from, don't be tempted by any of the plugin-looking files there that aren't part of JSDoc3 and that I didn't mention here - they're probably heavily in progress and not ready for sharing).

mathematical.coffee

unread,
Nov 22, 2012, 6:32:42 AM11/22/12
to jsdoc...@googlegroups.com
I'd like to update the links for the above plugins:


I'd also like to withdraw inheritdoc from the above list, because I've just added tests for it and realised it has many, many bugs (particularly with the @override tag, and also when @inherits occur in an order different to the order they appear in the file).

If I can get it working again, I'll repost it back up (and it will live at the above github link, **not** the bitbucket one).

mathematical.coffee

unread,
Nov 27, 2012, 7:15:58 PM11/27/12
to jsdoc...@googlegroups.com
A few more to add.

I'm re-adding inheritDoc, with a new URL. I've basically re-written it and am now much happier with it (have aded tests and so on for it)

inheritDoc
Tags @inheritdoc, @inheritparams and @override for inheriting of parameter/returns/function description documentation.
Status: I am satisfied with @inheritdoc and @inheritparams. The @override tag sort-of works but in a limited case (to be described)
Caveats: If @override is used on (say) Subclass#foo and Subclass @extends Class, the documentation is only properly taken from Class#foo if Class#foo is explicitly defined and documented in Class. So for example:
/** @class */
function GrandparentClass() {
    /** a function */
    this.foo = function () {};
}
/**@class
 * extends GrandparentClass */
function Class() {
}
/**@class
 * extends Class */
function Subclass() {
    /** @override */
    this.foo = function () {}
}
In the above, Subclass#foo won't get GrandparentClass#foo's documentation as you expect, because Class#foo isn't explictly documented (although it is there). This is because inherited documentation like this is only resolved in JSDoc after all the plugins run, so the inheritDoc plugin doesn't get a chance to walk up the ancestor tree (I think it's doable from within a plugin but it doesn't bug me enough to fix it).

relativeLinks
Description: Adds limited support for relative links, for example:
  • {@link #foo} in the documentation for a class or a method of it will automagically turn into {@link MyClass#foo};
  • likewise, {@link ~asdf} and {@link .fdsa} will turn into {@link MyClass~asdf} and {@link MyClass.fdsa}
  • works for modules/namespaces too: if you're documenting a module or any member of a module, {@link ~myMethod} (say) will link to {@link module:myModule~myMethod}.
Known issues:
  • There is no verification that the resolved links actually exist; so if you do {@link ~foo} from within MyClass, the link will be turned into {@link MyClass~foo} whether or not this exists.
  • The plugin basically looks for the object that a doclet is a memberOf and prepends that to the link. It will only take the closest parent, non-intelligently For example, if MyClass is in module:myModule, {@link #foo} from within the class documentation will resolve to {@link module:myModule~MyClass#foo}, but {@link ~MyClass} from within the class documentation will turn into {@link module:myModule~MyClass~MyClass} as it's assumed to be a link to an inner member of MyClass since it occurs within th documentation for MyClass.
Example:

/** A class.
* These will resolve to members in MyClass {@link #foo}, {@link ~foo} and {@link .foo}.
* So will {@link #bar}, even though this doesn't exist!
* @class
*/
function MyClass() {
    /** instance method foo
* @see ~foo
* @see {@link .foo} */
    this.foo = function (x) {
    };
    /** inner method foo */
    var foo = function () {
    };
}
/** The static method foo. */
MyClass.foo = function () {
};
// test in a namespace
/** A namespace.
* See {@link .foo} which will turn into MyNamespace.foo.
* @namespace */
var MyNamespace = {
    /** Foo. The event resolves to MyNamespace.my-event
* @type {Object}
* @property {number} x - see {@link .bar} (MyNamespace.bar)
* @fires .my-event
*/
    foo: {},
    /** function.
* @this .foo */
    bar: function () {
    }
    /** Event
* @event
* @name my-event
* @memberof MyNamespace
*/
};
// test an enum
/** An enum
* @enum */
var MyEnum = {
    /** value 1. see {@link .VAL2} */
    VAL1: 1,
    /** value 2. */
    VAL2: 2
};

autoNamespace 
Description: Automatically makes each documented file into its own namespace.

For example if I have files foo.js and bar.js, every symbol in foo.js will be in namespace Foo, while all symbols in bar.js are in namespace Bar.

Links from within foo.js or bar.js will attempt to be resolved within that namespace. For example if foo.js defines function myFunction, then {@link myFunction} from within foo.js will resolve to {@link Foo.myFunction}. However to link to a function in bar from within foo.js we still have to do {@link Bar.thatFunction}.

{@link Foo} from within foo.js will link to the namespace Foo. However, if foo.js also happens to have a symbol Foo, {@link Foo} will resolve to that symbol, {@link Foo.Foo}. In this case to link to the namespace rather than the symbol, one can use {@link namespace:Foo}.

Also, the automatic namespace will use the file's description/summary (from @overview) if provided and if it does not have its own description/summary.

To override the automatic namespace use tag @autonamespace as if it were a @namespace doclet. For example if I wanted everything in foo.js to be in namespace Foo2:

/** @autonamespace Foo2
 * [optional namespace description as for the @namespace doclet] */

See the instructions in the file for further information.
Example:
 
/** Namespace description. {@link MyClass} will resolve to MyNamespace.MyClass
* Also the name of the namespace will be MyNamespace (as opposed to the file name) because we
* used @autonamespace.
* @autonamespace MyNamespace
*/
// these @fires, @see, @extends etc all still resolve properly to MyNamespace.symbol
/** A class.
* @fires MyClass.ClassEvent
* @class */
function MyClass() {
}
/** An event belong to a class
* @event
* @name ClassEvent
* @memberof MyClass */
/** Corner case: a symbol with the same name as the namespace.
* NOTE: in this case {@link MyNamespace} will resolve to the symbol and
* {@link namespace:MyNamespace} will resolve to the namespace */
function MyNamespace() {
}

Luke Chavers

unread,
Jul 22, 2014, 9:40:22 AM7/22/14
to jsdoc...@googlegroups.com
These look very interesting.. I know its a year and a half later but hopefully they still work.

I will be giving them a test run soon!  Thanks for this..
Reply all
Reply to author
Forward
0 new messages