How to comment the sourcecode for JsDoc-Toolkit

From JSXGraph Wiki
Revision as of 16:23, 20 February 2013 by A WASSERMANN (talk | contribs)

There are 5 major elements to document using JsDoc-Toolkit: classes/objects, namespaces, elements, properties, and methods.

classes/objects

Tags important for documenting classes/objects:

/**
 * <general description for the constructor. the text until the first "." appears in the constructor summary, all the text appears in the detailed constructor description>
 * @class <class description. appears on top of the html page for that class>
 * @augments <class from which this class is inherited>
 * @param {<a comma separated list of all possible types this parameter can have>} <name of the parameter> <detailed description of this parameter>
 * @see <path to related object/class/member/method. see [1] for detailed description>
 */

example:

/**
 * Creates a new point object.
 * @class This is the Point class. 
 * It is derived from {@link GeometryElement} and stores all properties required
 * to move, draw a point.
 * @augments JXG.GeometryElement
 * @param {string,JXG.Board} board The board the new point is drawn on.
 * @param {array} coordinates An array with the affine user coordinates of the point.
 * @param {string} id Unique identifier for the point. If null or an empty string is given,
 *  an unique id will be generated by Board
 * @param {string} name Not necessarily unique name for the point. If null or an
 *  empty string is given, an unique name will be generated
 * @param {boolean} show False if the point is invisible, True otherwise
 * @param {boolean} withLabel If true, a label will be created and shown next to the point.
 * @see JXG.Board#generateName
 * @see JXG.Board#addPoint
 */
JXG.Point = function (board, coordinates, id, name, show, withLabel) {
...

instead of packing the parameter types into the doc comment you can use inline doclets. the above example then looks like:

 * @param board The board the new point is drawn on.
 * @param coordinates An array with the affine user coordinates of the point.
 * @param id Unique identifier for the point. If null or an empty string is given,
 *  an unique id will be generated by Board
 * @param name Not necessarily unique name for the point. If null or an
 *  empty string is given, an unique name will be generated
 * @param show False if the point is invisible, True otherwise
 * @param withLabel If true, a label will be created and shown next to the point.
 */
 JXG.Point = function(/** String,JXG.Board */ board, /** array */ coordinates, /** string */ id, /** string */ name, /** boolean */ show, /** boolean */ withLabel) {
 ...

these inline doclets have the advantage, that the type of the parameter is around that place, a programmer would expect it in other programming languages. from now on in this how to only inline doclets will be used for parameter types and function return value types.

namespaces

usually really short done, as in most cases only the @namespace is required. an example from MathNumerics.js:

/**
 * Math.Numerics namespace holds numerical algorithms, constants, and variables.
 * @namespace
 */
JXG.Math.Numerics = {}; 


elements

these are the elements created using the board.createElement-method and looks like classes/objects. but two more tags are required: @name and @pseudo. The first one tells jsdoc-toolkit to take the given alias to create a new html page for this symbol. the last one tells jsdoc that it should name this class "Element" instead of "Class" and to parse the @param tags in a special way. each @param tag holds one possible parent array combination, e.g. a free point can be constructed with 2 or 3 numbers. a contrained point can be constructed also by 2 or 3 numbers, 1 number and 1 function, 2 functions, 2 strings containing geonext-formatted coordinate calculations or 1 number and 1 string, ... etc. these informations are coded into a @param tag this way:

@param {<underscore separated list of comma separated lists of all possible parent element types} <commaseparated list of all possible parent array element names. optional parent elements are followed by an underscore> <description of this combination of parent array elements>

Example (the point example from above):

* @param {number,string,function_number,string,function_number,string,function} z_,x,y Parent elements can be two or three elements of type number, a string containing a GEONExT
* constraint, or a function which takes no parameter and returns a number. Every parent element determines one coordinate. If a coordinate is
* given by a number, the number determines the initial position of a free point. If given by a string or a function that coordinate will be constrained
* that means the user won't be able to change the point's position directly by mouse because it will be calculated automatically depending on the string
* or the function's return value. If two parent elements are given the coordinates will be interpreted as 2D affine euclidean coordinates, if three such
* parent elements are given they will be interpreted as homogeneous coordinates.
* @param {JXG.Point_JXG.Transformation} Point,Transformation A point can also be created providing a transformation. The resulting point is a clone of the base
* point transformed by the given Transformation. {see JXG.Transformation}.

This finally looks like:


This element has no direct constructor. To create an instance of this element you have to call JXG.Board.createElement with type "point".

Possible parent array combinations are:
{number|string|function} z  Optional
{number|string|function} x
{number|string|function} y

Parent elements can be two or three elements of type number, a string containing a GEONExT constraint, or a function which takes no parameter and returns a number. Every parent element determines one coordinate. If a coordinate is given by a number, the number determines the initial position of a free point. If given by a string or a function that coordinate will be constrained that means the user won't be able to change the point's position directly by mouse because it will be calculated automatically depending on the string or the function's return value. If two parent elements are given the coordinates will be interpreted as 2D affine euclidean coordinates, if three such parent elements are given they will be interpreted as homogeneous coordinates.


{JXG.Point} Point
{JXG.Transformation} Transformation

A point can also be created providing a transformation. The resulting point is a clone of the base point transformed by the given Transformation. {see JXG.Transformation}.



methods

pretty much like classes/objects. but without @class tag, of course, but with additional @return tag to explain what will be returned by the function/method. also a @type tag is required to declare all return value types that can occur. if a class returns nothing, undefined could be used. alternatively inline doclets can be used like in the following example from MathNumerics.js:

/**
 * Solve initial value problems numerically using Runge-Kutta-methods.
 * See {@link http://en.wikipedia.org/wiki/Runge-Kutta_methods} for more information on the algorithm.
 * @param butcher Butcher tableau describing the Runge-Kutta method to use.
 * @param x0 Initial value vector. If the problem is of one-dimensional, the initial value also has to be given in an array.
 * @param I Interval on which to integrate.
 * @param N Number of evaluation points.
 * @param f Function describing the right hand side of the first order ordinary differential equation, i.e. if the ode
 * is given by the equation <pre>dx/dt = f(t, x(t)).</pre> So f has to take two parameters, a number t and a
 * vector <tt>x</tt>, and has to return a vector of the same dimension as <tt>x</tt> has.
 * @return An array of vectors describing the solution of the ode on the given interval I.
 * @example
 * // A very simple autonomous system dx(t)/dt = x(t);
 * function f(t, x) {
 *     return x;
 * }
 * 
 * // We want to use the method of heun.
 * var method = JXG.Math.Numerics.predefinedButcher.Heun;
 * // Solve it with initial value x(0) = 1 on the interval [0, 2]
 * // with 20 evaluation points.
 * var data = JXG.Math.Numerics.rungeKutta(method, [1], [0, 2], 20, f);
 * 
 * // Prepare data for plotting the solution of the ode using a curve. 
 * var dataX = [];
 * var dataY = [];
 * var h = 0.1;        // (I[1] - I[0])/N  = (2-0)/20
 * for(var i=0; i&lt;data.length; i++) {
 *     dataX[i] = i*h;
 *     dataY[i] = data[i][0];
 * }
 * var g = board.createElement('curve', [dataX, dataY], {strokeWidth:2});
 * </pre><div id="d2432d04-4ef7-4159-a90b-a2eb8d38c4f6" style="width: 300px; height: 300px;"></div>
 * <script type="text/javascript">
 * var board = JXG.JSXGraph.initBoard('d2432d04-4ef7-4159-a90b-a2eb8d38c4f6', {boundingbox: [-1, 5, 5, -1], axis: true, showcopyright: false, shownavigation: false});
 * function f(t, x) {
 *     // we have to copy the value.
 *     // return x; would just return the reference.
 *     return [x[0]];
 * }
 * var data = JXG.Math.Numerics.rungeKutta(JXG.Math.Numerics.predefinedButcher.Heun, [1], [0, 2], 20, f);
 * var dataX = [];
 * var dataY = [];
 * var h = 0.1;
 * for(var i=0; i<data.length; i++) {
 *     dataX[i] = i*h;
 *     dataY[i] = data[i][0];
 * }
 * var g = board.createElement('curve', [dataX, dataY], {strokeColor:'red', strokeWidth:2});
 * </script><pre>
 */
JXG.Math.Numerics.rungeKutta = function(/** JXG.Math.Numerics.Butcher */ butcher, /** array */ x0,
                                        /** array */ I, /** number */ N, /** function */ f) /** array */ {


properties

not done yet... coming soon.

optional but highly recommended additional tags

example

this is used to include a source code example, e.g.:

* @example
* // Create a free point using affine euclidean coordinates 
* var p1 = board.createElement('point', [3.5, 2.0]);

don't forget to mask html entities like <, >, and &!

Even jsxgraph boards can be included, but for that a little trick is required. first you have to close the <pre>-tag and after the example ends you have to open another pre-Tag:

* </pre><div id="672f1764-7dfa-4abc-a2c6-81fbbf83e44b" style="width: 200px; height: 200px;"></div>
* <script type="text/javascript">
*   var board = JXG.JSXGraph.initBoard('672f1764-7dfa-4abc-a2c6-81fbbf83e44b', {boundingbox: [-1, 5, 5, -1], axis: true, showcopyright: false, shownavigation: false});
*   var p1 = board.createElement('point', [3.5, 2.0]);
* </script><pre>

deprecated

if something is left by historical reasons and shouldn't be used anymore, use the @deprecated tag to show the reader that this thing may be removed in future releases.

since

if something's brand new, use the @since <version> tag:

/**
 * Creates a new point object.
 * @class This is the Point class. 
 * It is derived from {@link GeometryElement} and stores all properties required
 * to move, draw a point.
 * @augments JXG.GeometryElement
 * @since 0.1
 * ...
 */

link

to link somewhere in the continuous text use {@link <path to jsxgraph object/element/method/property or just a hyperlink>}.

throws

VERY important tag to inform the reader about possibly thrown exceptions and why they may be thrown. e.g.:

* @throws {Exception} If {@link JXG.Math.Numerics.number_of_nodes} doesn't match
* {@link JXG.Math.Numerics.integration_type} an exception is thrown. If you want to use
* simpson rule respectively milne rule {@link JXG.Math.Numerics.number_of_nodes} must be dividable by
* 2 respectively 4.

see

to reference to objects or methods related to the documented. usage:

* @see JXG.Math.Numerics.NewtonCotes

private

if something's for core developer's eyes only, use this @private flag.

html tags

can be used, too. useful for lists, links, live jsxgraph examples in the docs, etc.