This is a tutorial on how to annotate your JS code for this documentation.

Foreword

All the documentation present is generated from special annotated comment blocks (described below) within the JS code.
Note that it does not matter where the comment blocks are placed in the file, or how the actual code looks like. The documentation tool does not inspect your JS code to infer or verify any information described in your comment blocks.
This is done purposely so that only the interface or function library is exposed to the user in this documentation. We do not want to expose here the internal state or structure of your library - which might be quite different from the interface itself! Developer notes should be left in normal comments.

Introduction

All annotated commend blocks look like this:

/**
 * This is a comment block. 
 * This text is the description of this block, which can be multiline
 * @annotation1 it can contain one or more annotations.
 * @annotation2 which may have additional information after it..
 */
The important part is that each annotated comment block starts with /**, ends with */ and each line within it starts with a *. So long as it adheres to this structure, the tab level where the comment sits at does not matter.

The description part can contain limited HTML tags for additional formatting. Supported tags are: <a>, <b>, <u>, <i>, <strong>, <tt>, <ul>, <ol>, <li>, <sup>, <sub>, <pre>, <samp>, <code>, <kbd> ."href" and "target" attributes are supported within the <a> tag.

Normal JS code comments like those starting with // or within /* */ will not be picked up.

The Documentation Tool expects each JS file that wants to be part of the documentation to add a comment block at the start of the file containing a @mXrap annotation.

/**
 * @mXrap
*/
This can be part of the library annotation (described below), which the tool also expects to be read at the beginning.
/**
 * This is a description of the Xrocketscience library
 * @library Xrocketscience
 * @mXrap
*/

Organisation

Code is organized into Libraries. A Library may contain zero or more Categories. Each Category may contain zero or more Functions. The Library may also contain zero or more Functions that are not part of any Category.
Functions are the actual function calls that can be invoked within mXrap table calculations.

In the example below, we declare a Xrocketscience library, containing:

  • A Xrocketscience.Construct category, containing a "buildRocket()" function
  • A Xrocketscience.Blast category, containing a "combust()" function
  • A "propel()" function in the library not under any category
/**
 * This is the rocket science library
 * @library Xrocketscience
 */
 
/**
 * This is the Xrocketscience.Construct category. 
 * @category Construct 
 */
 
/**
 * This is the Xrocketscience.Construct.buildRocket() function. This function is within the Construct category.
 * @function buildRocket 
 */ 
 
/**
 * This is the Xrocketscience.Blast category. Defining a new category automatically closes any current category.
 * @category Blast 
 */
 
/**
 * This is the Xrocketscience.Blast.combust() function. This function is within the Blast category.
 * @function combust 
 */
 
/**
 * Note that you can also use the annotations @endLibrary and @endCategory in a standalone comment block to "close" a category or library. 
 * However we don't think they will be required for 99% of the cases. Here we close the "Blast" category.
 * @endCategory
 */ 
 
/**
 * This is the Xrocketscience.propel() function. This function is outside of the Blast category, so it is within the library but not under any category.
 * @function propel 
 */ 

In some cases, you'll want to have multiple category hierarchies, e.g. having a Xrocketscience.Blast.Jet.TypeA category
The documentation system currently does not explicitly support multiple categories, but you can define each tier separately, and the sorting used in generating the library documentation page ensures they are placed in the correct nested order.

/**
 * This is the Xrocketscience.Blast category.
 * @category Blast 
 */

/**
 * This is the Xrocketscience.Blast.Jet category.
 * @category Blast.Jet
 */

/**
 * This is the Xrocketscience.Blast.Jet.TypeA category.
 * @category Blast.Jet.TypeA 
 */

Constants and Properties

Sometimes in libraries or categories, you want to define some constants, or properties that define behaviour for functions in the library/category.

For example, a constant could be like XMath.PI, and you might define it in library XMath as:

/**
 * A Math library
 * @library XMath
 * @mXrap
 */
 
/**
 * @constant {Number} PI 
 */
Lib.PI = 3.14159;
A constant is not intended to be modified by code, and is usually by convention in ALL CAPITALS.

A property, on the other hand, is something that is intended to be set-able by the user, perhaps to change a limit or behaviour of the library, for example XShapes.maximum_number_of_faces_limit:

/**
 * A Shapes library
 * @library XShapes
 * @mXrap
 */
 
/**
 * @property {Number} maximum_number_of_faces_limit the maximum number of faces this library will render before it throws an error. To avoid runaways.
 */
Lib.maximum_number_of_faces_limit = 10e6;

Status

mXrap documentation uses annotations to also specify the status of a Library, Category or Function. The status refers to how production ready the library is, or its intended audience. The statuses are, in ascending order of precedence:
Approved - for general use (@approved)
Beta - this is a work in progress (@beta)
Alpha - this is in the early stages of development. Use at your own peril! (@alpha)
ACG Only - this is only intended for ACG use. (@acgOnly)
Deprecated - this is no longer supported and may be removed in the future. Do not use! (@deprecated)
The default status is Alpha, but it will be overwritten by any specified annotation.

Status tags can be defined at the Library, Category or Function level. When determining the final status of a Category or Function, the statuses of itself and its containers are compared, and the status with the highest precedence is chosen. For example:
Case 1:
Library (@beta) => Beta
Category (no annotation) => Alpha (default)
Function (@alpha) => Alpha
Result: Library is Beta. Category is Beta, Function is Alpha (but other functions in the category may be Beta)

Case 2:
Library (@deprecated) => Deprecated
Category (no annotation) => Alpha (default)
Function (@alpha) => Alpha
Result: Library is Deprecated. Category is Deprecated, Function is Deprecated.

Function details

While Libraries and Categories only have a name, description and status, Functions also have - zero or more parameters, and an optional return value.

The @param annotation is used to define function parameters. Parameters must be defined in the order that they are listed in the method signature. Each @param annotation looks like:
@param {type} parameterName ...any additional information about the parameter...
type refers to the JS type of the parameter, which can be Object, Array, Number, Text (you can specify anything, so long as it makes sense to the user).
e.g.:

/**
 * This function copies all values from the input array to the output array
 * @function copyMyArray
 * @param {Array} out_array the output array
 * @param {Array} in_array the input array
 * @beta
*/
function copyMyArray(out_array, in_array) ...

The @return annotation is used to define the return type. It is similar to the @param annotation:
@param {type} returnName ...any additional information about the returned value...
Note - the returnName isn't important - its not provided in the code - but serves to provide information about what the value being returned signifies.
e.g.:

/**
 * This function copies all values from the input array to the output array, and returns the number of elements copied
 * @function copyMyArray
 * @param {Array} out_array the output array
 * @param {Array} in_array the input array
 * @return {Number} numElementsCopied the number of elements copied
 * @beta
*/
function copyMyArray(out_array, in_array) ...

Math formulae and equations

We use MathJax to render AsciiMath formulae and equations in the output documentation.

You can add AsciiMath formulae and equations by enclosing them in backticks (`), for example:
`sum_(i=1)^n i^3=((n(n+1))/2)^2`
generates:
`sum_(i=1)^n i^3=((n(n+1))/2)^2`
For more details, visit AsciiMath

Naming Conventions

This section lists some of the mXrap naming conventions.

  • Library and Category names usually start with a capital letter, e.g. XPlot, XPlot.Generate
  • Function names are in camelCase, and underscore maybe used to denote a variant of the function taking in different inputs, for example, e.g. XPlot.Generate.logInterval and XPlot.Generate.logInterval_array
  • When defining functions, output parameters are usually placed before input parameters.

Classes

Most of the functionality in mXrap libraries are defined as Functions organized in Libraries and Categories, as they are easily used by anyone who has used other scripting packages such as Matlab or Mathcad. However in some cases it may be easier to express or structure functionality in class-ic Javascript, which deals with objects, which may have state or functionality attached to them.

A Class is a description of an object, including its members (state) and methods (functions). Here's an example:
Since we are working with the Xrocketscience library, let's use a rocket as an example. Suppose the buildRocket() function returns a object of type "Rocket":

/**
 * Builds and returns a rocket
 * @function buildRocket
 * @returns {Rocket} rocket
 */

Now let us define a Rocket. Suppose a rocket has a mileage meter that shows how far its travelled, and a fuel gauge. It also has a method called moveTo(location).

/**
 * A Rocket to take us places
 * @class Rocket
 * @member {number} mileage
 */

// members can be defined with the class, or standalone
/**
 * @member {Number} fuelGauge
 */

// methods are defined similar to functions.
/**
 * @method moveTo
 * @param location place to move to
 * @return {Boolean} success returns whether the move was successful
 */

/**
 * @endClass
 */

Now when using this library we would expect in javascript:

   const XRocketScience = load('js/tutorial/xrocketscience.js');
   const myRocket = XRocketScience.buildRocket();
   
   print(myRocket.mileage); // returns mileage number via member
   print(myRocket.fuelGauge); // returns fuel gauge number via member
   myRocket.moveTo("Mars"); // move rocket to mars and returns whether the move was successful

To Dos

You can add a @TODO annotation anywhere in a @mXrap annotated file, either as part of another comment block or as a standalone block. This would not be shown within the library documentation, but would be picked up under the report as a To Do. This is useful for cases when:

  • You are halfway through coding a function and would like to add a note, e.g. @TODO document this
  • You are flagging an issue for the developer or documentor to look at on a function/category/class/library
/**
 * @TODO document me!
 */
const lib.newFunc = function halfwayCoding() { ...
...

/**
 * This is a function
 * @function myFunction
 * @TODO Should this be flagged as @alpha?
 */ 

You can also target a person by name to handle the TODO, or mention multiple people, via the curly braces.

/**
 * This is a function
 * @function myFunction
 * @TODO {CHUN} Should this be flagged as @alpha?
 */ 
 
/**
 * This is another function
 * @function myOtherFunction
 * @TODO {CHUN} Please discuss with {PAUL} on how to implement this function
 */ 
TODOs that are targetted/mentioned will appear under the person's name in the Todos page, otherwise they appear under "Unassigned".

Includes

As libraries get larger and more complex, it becomes useful to break up larger libraries into separate javascript files. For example, XProbMethods is defined in js/standard/xprobmethods.js but that file pulls in javascript code from js/standard/probMethods/RIF.js, js/standard/probMethods/RSM1.js and js/standard/probMethods/RSM2.js.

Previously the practice has been to define the "function signatures" as mXrap annotations in the parent xprobmethods.js file, even though the actual function code resides in the other files. This is a bad practice because we want the annotations and code to be in the same file (and preferably as close as possible within the file), so that the library maintainer can keep them in sync.

Hence we introduce the concept of include annotations. The @include annotation tells the mXrap annotation parser to include another javascript file, and parse its annotation contents.

/**
 * @include probMethods/RIF.js
 */ 
Note that the relative path to the file-to-include is specified.

Where parsing of organisational annotations (@library, @category, @function) are concerned, the annotations of the destination file are treated as if they were inserted into at point of the file. e.g. if you are in a category and the included file defines a function, that the function is deemed to be part of the category.

We recommend that files included this way define their own categories.

The destination file must be annotated at the top of the file as an mXrap include (otherwise its contents will not be pulled in:

/**
 * @mXrap
 * @isInclude
 */ 

Attachments

Sometimes it is convenient to include an attachment to a specific library, category, function, class or method. This could be a referenced paper, a zipped data set or a more indepth tutorial PDF. You can do this using the @attachment annotation, in the manner:

@attachment file-location More Descriptive Text
for example:
@library Xstats
 @attachment stats/Using_Xstats.pdf Using Xstats - an indepth tutorial
and within the description for the attached library, category, function, class or method, it will provide a link to the relevant resource.