CHAPTER 2

image

Documenting JavaScript

In the previous chapter, we looked at object-oriented JavaScript and coding conventions. The purpose of writing OO code and establishing conventions is to ensure that the code is legible and understandable for a developer. A JavaScript engine in a browser isn’t concerned about how neatly your code is written, or whether it makes sense to you—it merely follows a set of rules on whatever it’s been given. It’s more important for you and your team to understand the code you’ve written and how to work with it as this simplifies the task of maintaining your code base. Code maintainability means that teams of any size can collaborate on the same set of files with a common understanding of how to add, amend, and remove parts of that code with consistent results. In addition to the code itself being understandable, you will find you need to add small comments or larger blocks of documentation to explain to other developers, including yourself if you don’t remember your reasoning in future, what task a particular section of code performs and how it is to be used.

There are two groups of users who benefit from good documentation, which depends on the intended audience for your code. The first group is yourself and your fellow project collaborators. Good documentation keeps everyone aware of what your code does, how it does it, and why it does it, reducing the chance of confusion and errors being introduced.

The second group is other developers, unrelated to your project. If your project exposes public functions as some kind of API (Application Programming Interface) then you will need to ensure that your documentation is up-to-date, readable, and understandable, preferable with working examples to aid its adoption by other developers. Imagine if jQuery had poor documentation, it certainly wouldn’t have been adopted as quickly as easily as it has been. Good, thorough documentation is key to getting adoption of your code to a wider group of developers.

Documentation can take many forms from a few key comments in a code file to an entire website dedicated to describing a code base; each suits different situations more appropriately. This chapter will focus largely on a structured form of documentation using specially formatted tags within comments in JavaScript code files, and will use this structure to generate a fully working documentation website without writing a line of HTML or CSS.

Inline and Block Comments

Sometimes code itself doesn’t explain exactly what’s going on and you just can’t get away from adding comments to your code to make that code more understandable. It’s fine to comment code but as a general rule, try to let the code do the talking. If you can avoid adding a comment by better naming a variable, then do that. If you need to add a comment to add value to your code, use either an inline comment, which is designed for use on a single-line of your JavaScript code:

// JavaScript recognises this line a comment because of the double slashes at the start

Or use a block comment, which is designed to span multiple lines of code:

/*
 * JavaScript recognises this as a block comment because of the slash / asterisk combination
 * at the start and the asterisk / slash combination at the end. Many developers choose to
 * begin each line of commented text with an asterisk and apply spacing such that each
 * asterisk lines up with the one from the previous line.
 */

Structured JavaScript Documentation

We could simply create a separate documentation file containing the usage notes and examples that describe our code, however, we’d have to ensure that this file was kept up to date whenever changes were made to the code itself, which can be time-consuming and most likely will not be done, meaning that it will forever be out of sync with the code it was written to describe.

In my opinion, the best way to create documentation is to add the usage notes and examples straight into block comments within the code file itself, right where the code is. In that way, it’s clear to a developer adding or changing the code that the documentation they see surrounding it needs updating too, giving a better chance of the documentation staying up to date.

We’ve got a strategy, therefore, for ensuring that documentation is kept relevant, however it’s not so easy to read if it’s right with the source code and all you want to read is the documentation itself. We need a way of extracting the documentation out of the source code, therefore, into a more presentable form—ideally, this will be a simple case of running a program to do this for us, as we don’t want to perform the extraction ourselves manually – we’re developers and we just don’t have the patience for that!

Fortunately, several programs exist to extract specially formatted documentation from source code files and present it within a simple webpage, in an easy to use format. Such programs include JSDoc (http://bit.ly/jsdoc_3), dox (http://bit.ly/d_o_x), and YUIDoc (http://bit.ly/yui_doc). Industry preference seems to be moving toward the latter and that’s what we’ll use to generate our documentation throughout the rest of this chapter.

The YUIDoc Documentation Format

YUIDoc does not process and understand any code in your source files; rather, it observes only the specially formatted block comments that you write yourself around your code. In my experience of using other documentation processors, some automatic processors often miss important factors that I understand about my code but they don’t. You’re then forced to add extra documentation manually in order to override its automatic processor. My preference is, therefore, for a processor that understands only what I tell it, so that I can be clear and explicit about my code in my documentation without any spurious information finding its way into my documentation.

YUIDoc will read only block comments from a file, and even then will ignore all that do not begin with the combination /**, as shown below. You can optionally add extra asterisk (*) characters to the beginning of each line of the comment to continue to denote that each line is part of the same comment and to line each up. Code editors such as Sublime Text (http://bit.ly/sublime_text) will do this automatically for you:

/**
 * This will be read by YUIDoc
 */

/*
 * This will not
 */

/***
 * Neither will this
 */

Now we know how to get YUIDoc to read a comment block, we need to know what to put inside the block in a format that YUIDoc can understand. YUIDoc supports @-tags, small labels that each start with the @ character followed by other names and information as relevant. YUIDoc has two sets of tags in its vocabulary, primary tags and secondary tags. Each comment block that describes some surrounding code must include one, and only one, primary tag, followed by as many or as few secondary tags as necessary.

Rather than list out every tag and its definition, let’s look at some real-life use cases and see which tags are appropriate for which case.

Documenting “Classes”, Constructors, Properties and Methods

We looked closely at object-oriented JavaScript coding in Chapter 1, in which we covered the creation of “classes” and associating methods and properties to them. Let’s take one of our examples from that chapter and add some basic documentation comments to it in YUIDoc format.

Listing 2-1 defines a “class” named Accommodation using the Class.create method from Listing 1-19, with a constructor function named initialize, two public properties, isLocked and isAlarmed, and two public methods, lock and unlock.

Listing 2-1. A simple JavaScript “class” that needs documenting

var Accommodation = Class.create({
    isLocked: true,
    isAlarmed: true,
    lock: function() {
        this.isLocked = true;
    },
    unlock: function() {
        this.isLocked = false;
    },
    initialize: function() {
        this.unlock();
    }
});

We’ll start our documentation at the top, using YUIDoc’s @class tag for marking up a “class”. The tag is preceded by a definition of the “class”, and followed by the name of the “class”. We include the name since YUIDoc’s parser only reads these formatted comments and doesn’t execute or parse your code for variable names. First, we describe the “class”, leave an empty line, then we place the YUIDoc tags.

/**
 * A "class" defining types of accommodation
 *
 * @class Accommodation
 * @constructor
 */

We start the specially formatted comment with a simple text description of the “class” we’re defining. This could be as long or as short as we like, spanning multiple lines if needed. We then start each new line with a YUIDoc tag, the first being @class followed by the “class” public variable name, and then adding a new line with the @constructor tag, which indicates that the variable is a constructor function from which object instances can be created. The beauty of YUIDoc, I believe, lies in the fact that it doesn’t try and parse your code to extrapolate documentation by usage of variables and functions. In this case, the fact we created a constructor function and “class” using Class.create instead of defining a simple function won’t matter to YUIDoc as long as the correct @-tags are used to describe it. Another documentation engine might have been thrown by this approach to declaring a “class” and might have returned different documentation altogether to what we’d expect.

You may have a “class” in your code that is not intended to be instantiated with the new keyword each time but, rather, is instantiated itself after definition, and the rest of your code should use that single instantiation. This is known as a singleton, or static “class”, and can be denoted in your documentation by using the @static tag instead of the @constructor tag with your “class” definition, as shown in Listing 2-2.

Listing 2-2. Documentating a static “class”

/**
 * A static "class" containing methods for reading and writing browser cookies
 *
 * @class Cookies
 * @static
 */

// A self-instantiating "class" such as this is known as a singleton or static "class"
var Cookies = (function() {
    // Properties and methods to get and set cookie values go here…
}());

Documenting a property follows a similar pattern to the “class” itself; we create the formatted comment immediately above the property we’re documenting in our code.

/**
 * Denotes whether the accommodation is currently locked
 *
 * @property {Boolean} isLocked
 */

After our property definition, we define our property by name to YUIDoc using the @property tag. Note that we can declare the type within curly braces between the @-tag and the property name. This is useful for other developers to be aware of the correct value types to use for your properties, so it’s especially important that you remember to add this into your documentation. You can use any of the default types available in JavaScript, such as Boolean, String, Number, Object, Array, Date, Function, as well as any custom “class” types you create yourself within your code.

Documenting methods works in a very similar way to properties except that we use the @method tag and don’t need to specify the data type, because methods are always of the Function type.

/**
 * Unlocks the accommodation
 *
 * @method unlock
 */

Listing 2-3 shows the full documented version of the Accommodation “class” from Listing 2-1.

Listing 2-3. A simple, fully-documented JavaScript “class”

/**
 * A "class" defining types of accommodation
 *
 * @class Accommodation
 * @constructor
 */

var Accommodation = Class.create({

    /**
     * Denotes whether the acommodation is currently locked
     *
     * @property {Boolean} isLocked
     */

    isLocked: true,

    /**
     * Denotes whether the acommodation is currently alarmed—thieves beware!
     *
     * @property {Boolean} isAlarmed
     */

    isAlarmed: true,

    /**
     * Locks the accommodation
     *
     * @method lock
     */

    lock: function() {
        this.isLocked = true;
    },

    /**
     * Unlocks the accommodation
     *
     * @method unlock
     */

    unlock: function() {
        this.isLocked = false;
    },

    /**
     * Executed automatically upon creation of an object instance of this "class".
     * Unlocks the accommodation.
     *
     * @method initialize
     */

    initialize: function() {
        this.unlock();
    }
});—

Specifying Inputs Parameters and Return Values of Methods

The methods we documented in Listing 2-3 contained no inputs or outputs, so documenting them was as simple as describing the purpose of the function. To mark up a method with a description of its inputs and outputs, which are essential if other developers are to understand how your method should be used, you add the @param and @return tags to the @method tag we’ve seen already. Take a look at the following method, which we’ll add into our Accommodation “class” from Listing 2-1.

alarm: function(message) {
    this.isAlarmed = true;
    alert("Alarm is now activated. " + message);
    return this.isAlarmed;
}

We would add documentation to this method, detailing what the method does, along with its inputs and outputs, each listed on a separate line.

/**
 * Activates the accommodation's alarm and displays a message to that effect
 *
 * @method alarm
 * @param {String} message The message to display once the alarm is activated
 * @return {Boolean} The current activation state of the alarm
 */

Note that @param is similar to @property in that the type of the input parameter should be specified; unlike @property, however, the description of the parameter should immediately follow its name. The @return tag requires that we also specify the data type of the returned value within curly braces, followed by a description of what that value represents.

You may have written your code to group together the inputs to one of your methods into a single object literal parameter, as recommended in Chapter 1. This can be documented by listing each property in the object literal as a separate parameter, using dot notation to indicate each as part of the same object.

/**
 * Set all object instance properties in one shot
 *
 * @method setProperties
 * @param {Object} options Properties object
 * @param {Boolean} options.isAlarmed Denotes whether the accommodation is alarmed
 * @param {Boolean} options.isLocked Denotes whether the accommodation is locked
 * @param {String} options.message Message to display when alarm is activated
 */

Accommodation.prototype.setProperties(options) {
    options = options || {};

    this.isAlarmed = options.isAlarmed || false;
    this.isLocked = options.isLocked || false;
    this.message = options.message || "Alarm activated!";
};

Documenting Optional Method Input Parameters

If you have methods containing optional parameters, you can denote these in YUIDoc format by surrounding the parameter name in square brackets.

/**
 * Activates the accommodation's alarm, optionally displaying a custom message
 *
 * @method alarm
 * @param {String} [message] Custom message to display once the alarm is activated
 * @return {Boolean} The current activation state of the alarm
 */

Certain optional input parameters might have default values if the optional value is not provided. In our example, we may wish to default the optional message input parameter to a specific text string. We can denote this in YUIDoc format by following the parameter name with = and then by the default value for that parameter.

/**
 * Activates the accommodation's alarm, optionally displaying a custom message
 *
 * @method alarm
 * @param {String} [message=Alarm activated!] Custom message to display when alarm is activated
 * @return {Boolean} The current activation state of the alarm
 */

Documenting a Property Containing a Constant Value

In Chapter 1, we looked at denoting “constant” variables, or magic numbers, using capital letters. We can denote constants in our YUIDoc format documentation using the @final tag:

/**
 * The mathemtical constant Pi
 *
 * @property PI
 * @final
 */

var PI = 3.1415;

Documenting Private, Protected and Public Methods and Properties

For the benefit of yourself and other developers, you should document the public, protected and private properties and methods in your code. A method or property can be denoted as being private simply by adding the @private tag on a line by itself in your documentation, and protected properties can be marked with the @protected tag. Listing 2-4 shows a full documented “class” with public, protected and private properties and methods, taken from code we wrote in Chapter 1.

Listing 2-4. Fully documented “class” containing private and public methods and properties

/**
 * A "class" defining types of accommodation
 *
 * @class Accommodation
 * @constructor
 */

var Accommodation = (function() {
    function Accommodation() {}

    /**
     * Denotes whether the property is currently locked
     *
     * @property {Boolean} _isLocked
     * @protected
     */

    var _isLocked = false,

        /**
         * Denotes whether the property is currently alarmed
         *
         * @property {Boolean} _isAlarmed
         * @private
         */

        _isAlarmed = false,

        /**
         * Message to display when the alarm is activated
         *
         * @property {String} _alarmMessage
         * @protected
         */

        _alarmMessage = "Alarm activated!";

    /**
     * Activates the alarm
     *
     * @method _alarm
     * @private
     */

    function _alarm() {
        _isAlarmed = true;
        alert(_alarmMessage);
    }

    /**
     * Disables the alarm
     *
     * @method _disableAlarm
     * @private
     */

    function _disableAlarm() {
        _isAlarmed = false;
    }

    /**
     * Locks the accommodation
     *
     * @method lock
     */

    Accommodation.prototype.lock = function() {
        _isLocked = true;
        _alarm();
    };

    /**
     * Unlocks the accommodation
     *
     * @method unlock
     */

    Accommodation.prototype.unlock = function() {
        _isLocked = false;
        _disableAlarm();
    };

    /**
     * Returns the current lock state of the accommodation
     *
     * @method getIsLocked
     * @return {Boolean} Indicates lock state, ‘true' indicates that the accommodation is locked
     */

    Accommodation.prototype.getIsLocked = function() {
        return _isLocked;
    };

    /**
     * Sets a new alarm message to be displayed when the accommodation is locked
     *
     * @method setAlarmMessage
     * @param {String} message The new alarm message text
     */

    Accommodation.prototype.setAlarmMessage = function(message) {
        _alarmMessage = message;
    };

    return Accommodation;
}());

Documenting Inherited “Classes”

From the material covered in Chapter 1, we know how to exhibit inheritance through our code, but we need to represent relationships between parent and subclasses in our documentation also. We can use the YUIDoc @extends tag to denote which “class” is the parent of the currently documented “class”.

/**
 * Define a "class" representing a house
 *
 * @class House
 * @constructor
 * @extends Accommodation
 */

function House() {};
House.prototype = new Accommodation();

/**
 * Locks the house and activates the alarm
 *
 * @method lock
 */

House.prototype.lock = function() {
    Accommodation.prototype.lock.call(this);
    this.alarm();
};

Documenting Chained Methods

Your documentation can be marked up to denote that certain methods in your code can be chained together, using the @chainable tag. As we saw in Chapter 1, this simply involved returning the context of the method call at the end of the method so the same methods are available to be immediately called:

/**
 * Locks the house and activates the alarm
 *
 * @method lock
 * @chainable
 */

House.prototype.lock = function() {
    Accommodation.prototype.lock.call(this);
    this.alarm();
    return this;
};

Documenting Groups of Related “Classes”

Your code files may contain several “classes”, all of which share a similar grouping or related meaning to each other. In many cases, this grouping will be form naturally as a set of inherited “classes” from a single parent “class”. You can denote this grouping to YUIDoc using the @module tag and the name of the grouping, of which at least one such tag should exist within your code base, even if that grouping contains only a single “class”.

/**
 * Group of accommodation-related "classes"
 *
 * @module Accommodation-related
 */

Should you wish to refine your groupings further, you can use the @submodule tag together with @module to represent a subgrouping module of “classes” in your code.

/**
 * House-specific "classes"
 *
 * @module Accommodation-related
 * @submodule House-specific
 */

Documenting Events

If you’re writing code that triggers custom events in your code, with listener functions to be called when such events are triggered, you should document your events by name using the @event tag, and describing any parameters that get passed to any functions listening for that event to trigger, using the @param tag:

/**
 * Fired when the accommodation is alarmed
 *
 * @event accommodationAlarmed
 * @param {String} message The message that was shown when the accommodation was alarmed
 */

Documenting Code Examples

Sometimes text-based documentation is no substitute for a code example. That’s why YUIDoc contains the ability to mark up code within your structured documentation comments as an example usage of the code that follows, by using the @example tag. You can specify as many examples as you like, separating each with another @example tag. Example code should be indented by four spaces or one tab character, for reasons that will become clear further in this chapter when we discuss Markdown formatting.

/**
 * Sets a new alarm message to be displayed when the accommodation is locked
 *
 * @method setAlarmMessage
 * @example
 *     var myAccommodation = new Accommodation();
 *     myAccommodation.setAlarmMessage("My alarm is enabled – thieves beware! ");
 *     myAccommodation.alarm(); // Alerts "My alarm is enabled – thieves beware! "
 *
 * @example
 *     var myAccommodation = new Accommodation();
 *     myAccommodation.setAlarmMessage(); // Leave message blank
 *     myAccommodation.alarm(); // Alerts an empty box with no message
 */

Other YUIDoc Documentation Tags

In this chapter, we’ve covered the documentation tags that you’ll need in probably 90 percent of real-life cases. As you become more familiar with documenting your own code, however, you may find you need to document aspects of your code that haven’t been explained in this chapter. To see the full list of available tags for use with YUIDoc, visit the official syntax reference site via http://bit.ly/yuidoc_syntax.

Expressive Documentation Formatting – Markdown

Rather than writing longer-form “class”, method and property descriptions and usage documentation in HTML markup, where as a developer it becomes fairly difficult read, it’s possible to use a more developer-friendly format, known as Markdown— http://bit.ly/markdown_format.

John Gruber and Aaron Swartz developed Markdown in 2004 as a simple way for developers to write documents in plain text that can be easily read as plain text but just as easily transformed into HTML for easier reading. It uses conventions already present in plain text messages of the time, notably in emails and on newsgroups. It has become popular for generating rich text on sites such as GitHub, Stack Overflow, and SourceForge without the need to write HTML.

Using Markdown in your structured documentation will help your documentation be rich and expressive without overbloating your source code files or making them any harder to read. YUIDoc supports the Markdown format for free-form documentation within descriptions and examples, allowing for very expressive and thorough documentation to be produced. It is therefore important to become familiar with the format in detail. Let’s take a look through some of the most common ways of writing Markdown and the HTML outputs these produce when run through a Markdown processor, such as the one present within YUIDoc.

Grouping Content Under Headings

The HTML heading tags <h1> through <h6> can be produced as the output of a block of markdown text using the forms shown in the example below:

A Main Heading
==============

A Secondary Heading
-------------------

# Alternative Form Of Main Heading, aka Header Level 1
## Alternative Form Of Secondary Heading, aka Header Level 2
### Header Level 3
#### Header Level 4 ####
##### Header Level 5
###### Header Level 6 ######

This block of Markdown produces the following when processed into HTML:

<h1>A Main Heading</h1>
<h2>A Secondary Heading</h2>
<h1>Alternative Form Of Main Heading, aka Header Level 1</h1>
<h2>Alternative Form Of Seconday Heading, aka Header Level 2</h2>
<h3>Header Level 3</h3>
<h4>Header Level 4</h4>
<h5>Header Level 5</h5>
<h6>Header Level 6</h6>

Visually comparing the markdown input to the HTML output should reveal to you just how simple to read and write Markdown is compared to the relatively tricky-to-scan HTML output.

Note the two possible forms for main and secondary headings, and also the obsolete end markers on the level 4 and 6 headers in the original Markdown. These both are purely to allow easier to read input without affecting the output, feel free to use any approach you see fit according to which appearance you prefer.

Breaking Lines And Creating Paragraphs

Creating paragraphs of text using markdown requires no special symbols; simply add two line breaks between one block of text and another to produce a <p> tag around each block in the resulting HTML.

80 days around the world, we'll find a pot of gold just sitting where the rainbow's ending. Time—we'll fight against the time, and we'll fly on the white wings of the wind.

Ten years ago a crack commando unit was sent to prison by a military court for a crime they didn't commit. These men promptly escaped from a maximum-security stockade to the Los Angeles underground.

The markdown shown in the example here will be converted to the following HTML output.

<p>80 days around the world, we'll find a pot of gold just sitting where the rainbow's ending. Time—we'll fight against the time, and we'll fly on the white wings of the wind.</p>

<p>Ten years ago a crack commando unit was sent to prison by a military court for a crime they didn't commit. These men promptly escaped from a maximum-security stockade to the Los Angeles underground.</p>

You might assume from this that to create a line break in the HTML output rather than a paragraph break you would simply include a single line break in your Markdown file, but this is not the case. A single line break on its own in Markdown will flow the output text together into a single paragraph.

80 days around the world, we'll find a pot of gold just sitting where the rainbow's ending.
Time—we'll fight against the time, and we'll fly on the white wings of the wind.

The example here produces the following HTML output after processing.

<p>80 days around the world, we'll find a pot of gold just sitting where the rainbow's ending.
Time—we'll fight against the time, and we'll fly on the white wings of the wind.</p>

To generate a HTML line break <br /> in the output, you must precede your line break in Markdown with two or more spaces. This will be at the end of the line before so won’t be seen visually when reading the input file.

80 days around the world, we'll find a pot of gold just sitting where the rainbow's ending.
Time—we'll fight against the time, and we'll fly on the white wings of the wind.

The image symbols at the end of the first line in the example here denote the use of the space character, so ensure that you do not use the image character itself. Processing this Markdown input produces the following HTML output.

<p>80 days around the world, we'll find a pot of gold just sitting where the rainbow's ending.<br />Time—we'll fight against the time, and we'll fly on the white wings of the wind.</p>

Creating Lists

Both ordered and unordered lists can be represented through markdown and interpreted into their correct HTML tags.

An unordered, or bulleted, list can be represented using asterisks (*), hyphens (-), or pluses (+) as bullet points, each followed by one or more space characters, or tab characters, meaning it’s very flexible and you can use whichever feels most natural to you.

* Monkey
* Donkey
* Wonky

-       Monkey
-       Wonky
-       Donkey

+ Donkey
+ Monkey
+ Wonky

The example shown produces the following HTML output once processed. Observe that the HTML for each list is identical, despite the different bullets used in the original markdown list.

<ul>
    <li>Monkey</li>
    <li>Donkey</li>
    <li>Wonky</li>
</ul>

<ul>
    <li>Monkey</li>
    <li>Wonky</li>
    <li>Donkey</li>
</ul>

<ul>
    <li>Donkey</li>
    <li>Monkey</li>
    <li>Wonky</li>
</ul>

Ordered lists can be generated by beginning each line with a number, followed by a period then one or more tabs or space characters. The actual numbers used in the markdown file don’t matter; they will be processed as a single ordered number list starting from the number 1. This is actually beneficial to the person writing the markdown text as they need only set all numbers to the same digit, meaning they don’t have to reorder the numbers if they add an extra item to the list.

1. Monkey
2. Donkey
3. Wonky

1.      Monkey
1.      Wonky
1.      Donkey

1. Donkey
2. Monkey
3. Wonky

The example produces the following HTML output once processed. Observe that the HTML for each list is identical, despite the different numbers used in the original markdown list.

<ol>
    <li>Monkey</li>
    <li>Donkey</li>
    <li>Wonky</li>
</ol>

<ol>
    <li>Monkey</li>
    <li>Wonky</li>
    <li>Donkey</li>
</ol>

<ol>
    <li>Donkey</li>
    <li>Monkey</li>
    <li>Wonky</li>
</ol>

Not all lists are flat like the examples we’ve seen so far; you may wish to nest lists inside each other to create hierarchy. Fortunately, this can be achieved using markdown by simply indenting a child list item by four spaces, or one tab character.

* Monkey
    * Wonky
* Donkey

1. Monkey
    1. Wonky
1. Donkey

The code in the example generates the following HTML output once processed. Notice the nesting of the list items.

<ul>
    <li>Monkey
        <ul>
            <li>Wonky</li>
        </ul>
    </li>
    <li>Donkey</li>
</ul>

<ol>
    <li>Monkey
        <ol>
            <li>Wonky</li>
        </ol>
    </li>
    <li>Donkey</li>
</ol>

Paragraphs can be placed around list item text simply by adding a line break between items in the list. You can include multiple paragraphs of text per list item simply by indenting each extra paragraph by four spaces, or one tab character.

*   Monkey

    A monkey is a primate of the Haplorrhini suborder and simian infraorder.

*   Donkey

    The donkey or ass, Equus africanus asinus, is a domesticated member of the Equidae or horse family.

This example produces the following HTML output once processed.

<ul>
    <li>
        <p>Monkey</p>
        <p>A monkey is a primate of the Haplorrhini suborder and simian infraorder.</p>
    </li>
    <li>
        <p>Donkey</p>
        <p> The donkey or ass, Equus africanus asinus, is a domesticated member of the Equidae or horse family.</p>
    </li>
</ul>

Emphasizing Text

Using markdown, you can emphasize text within a sentence by using either asterisk (*) or underscore (_) characters around the text to be emphasized.

Donkeys are *not* monkeys.##
I repeat, Donkeys are _not_ monkeys.

The example produces the following HTML output once processed. Note the italicized text when emphasis is used.

<p>Donkeys are <em>not</em> monkeys.<br />
I repeat, Donkeys are <em>not</em> monkeys.</p>

You can add extra emphasis by doubling up the asterisk or underscore characters.

Donkeys are **really** not monkeys.##
I repeat, Donkeys are __really__ not monkeys.

This example produces the following HTML output once processed. Note the use of embolded text when stronger emphasis is used in the markdown document.

<p>Donkeys are <strong>really</strong> not monkeys.<br />
I repeat, Donkeys are <strong>really</strong> not monkeys.</p>

Displaying Code

There are two ways to demark snippets of code in Markdown format: an inline method and a block method. The former is denoted by backtick (`) characters surrounding the code and is for use where you wish to include a small portion of code as part of a line of text. The latter is for use to show one or more lines of code together and is denoted by simply indenting each line of code by four space characters or one tab character. This is the reason why when we use the @example YUIDoc tag, we indent the code listed alongside it.

Simply install Grunt by typing `npm install grunt` at the command line.

    <!doctype html>
    <html>
        <head></head>
    </html>

The example shown produces the following output HTML once processed. Note that any HTML tags have some of their characters replaced with entities so they render as text instead of attempting to parse as the tags they represent.

<p>Simply install Grunt by typing <code>npm install grunt</code> at the command line.</p>

<pre><code>&lt;!doctype html&gt;
&lt;html&gt;
    &lt;head&gt; &lt;/head&gt;
&lt;/html&gt;</code></pre>

Adding Quotes

To quote a citation within a paragraph of its own, simply precede the text with a right-facing angle bracket followed by one or more spaces or tab characters. Multiple paragraphs can be nested within a block quote by including empty quote lines to delimit each paragraph.

> Little Henry took his book one day and went into the garden to study. He sat where the arbor cast a pleasant shade, and he could smell the fragrance of the flowers that he himself had planted.
>
> At times, he would forget his book while listening to the music of the birds, or gazing at the peonies and tulips, but he would soon think again of his lesson, and commence studying with new zeal.

This example produces the following output once processed to HTML.

<blockquote>
    <p>Little Henry took his book one day and went into the garden to study. He sat where the arbor cast a pleasant shade, and he could smell the fragrance of the flowers that he himself had planted. </p>
    <p>At times, he would forget his book while listening to the music of the birds, or gazing at the peonies and tulips, but he would soon think again of his lesson, and commence studying with new zeal.</p>
</blockquote>

Linking To URLs

Linking to a URL is as simple as including that URL in your Markdown-formatted content. The URL can be written as-is, or by wrapping it within angle brackets, < and >. Both absolute and relative URLs are permitted.

For more, see http://www.google.com or <http://www.bing.com>

This example produces the following HTML once processed.

For more, see <a href="http://www.google.com">http://www.google.com</a> or <a href="http://www.bing.com">http://www.bing.com<a>

More often than not, however, you will want to link specific text to a URL. This is achieved by wrapping the text to be linked within square brackets, [ and ], and then including the link URL within standard brackets immediately after.

One popular search engine is [Google](http://www.google.com)

This example produces the following HTML output once processed.

One popular search engine is <a href="http://www.google.com">Google</a>

Finally, Markdown supports the use of reference links, a sort-of look up table of links used throughout a document. This allows the author of the markdown file to move all link URLs to another point in the document, commonly at the end, to make the rest of the document easier to read. Each link is then assigned a reference name or number within square brackets, separated from the URL by a colon character (:) and one or more spaces or tab characters. The link can then be referred to by this same name of number within square brackets throughout the rest of the markdown content. Reference names themselves may contain any combination of letters, numbers, spaces and punctuation, but note that they are not case sensitive.

Popular search engines include [Google][1], [Bing][2], and [Yahoo][yahoo], but the most popular today is [Google][1].

[1]: http://www.google.com
[2]: http://www.bing.com
[yahoo]: http://www.yahoo.com

The following HTML is produced after processing. Note that the reference list itself is not displayed in the output.

Popular search engines include <a href="http://www.google.com">Google</a>, <a href="http://www.bing.com">Bing</a>, and <a href="http://www.yahoo.com">Yahoo</a>, but the most popular today is <a href="http://www.google.com">Google</a>.

If you would prefer to add a title attribute to the link tag in the HTML output, you can supply this to the markdown content with the use of quotation marks following the link URL. This applies to both inline and reference links.

The most popular search engine today is [Google](http://www.google.com "Visit Google"), followed by [Bing][1] and [Yahoo][2].

[1]: http://www.bing.com "Visit Bing"
[2]: http://www.yahoo.com "Visit Yahoo"

The example shown produces the following HTML output once processed.

The most popular search engine today is <a href=http://www.google.com title="Visit Google">Google</a>, followed by <a href=http://www.bing.com title="Visit Bing">Bing</a> and <a href=http://www.yahoo.com title="Visit Yahoo">Yahoo</a>.

Inserting Images

The syntax for adding images to markdown content is very similar to the link syntax seen already. The main difference is that it is denoted as an image by a preceding exclamation point (!) character with no extra spaces or tab characters. This is then followed by a name placed within square brackets, which will produce an alt attribute containing that text in the resulting HTML output. The image URL itself is then placed within brackets, and providing an optional title in quotation marks after the URL adds a title attribute in the resulting HTML output, once processed.

![A squirrel](/path/to/squirrel-image.jpg)
![Homepages](http://www.homepages.com/image.jpg "Image from homepages.com")
![Company Logo][logo]
![Main Image][1]

[logo]: /path/to/logo.png
[1]: /path/to/main.jpg "The Main Page Image"

The example shown produces the following HTML output once processed.

<img src="/path/to/squirrel-image.jpg" alt="A squirrel" />
<img src="http://www.homepages.com/image.jpg" alt="Homepages" title="Image from homepages.com" />
<img src="/path/to/logo.png" alt="Company Logo" />
<img src="/path/to/main.jpg" alt="Main Image" title="The Main Page Image" />

Creating Horizontal Rules

To divide up sections in your markdown content, you insert a horizontal divider. This can be achieved in markdown using three or more asterisks (*), hyphens (-) or underscores (_) together on their own line. Unlike some other markdown rules, you can use spaces between these characters without affecting the output, but you may not mix the three types of characters on the same line.

***
---
___
* * *
- - - -
______________

Each example shown produces exactly the same HTML output once processed, as shown below.

<hr />

Using Backslash To Insert Reserved Characters

You will have seen that certain characters have specific meanings in markdown and get converted into HTML. If you want to use one of these characters in your markdown without it being converted, markdown provides a mechanism to do that—simply insert a backslash () character before the character that would otherwise be replaced. This works for the following characters:

  backslash
`  backtick
*  asterisk
_  underscore
{} curly braces
[] square braces
() parentheses
#  hash
+  plus
-  minus (hyphen)
.  dot
!  exclamation point

For Everything Else, There’s HTML

If you find you need to represent something that just isn’t supported by Markdown’s set of formatting rules, you needn’t be downhearted. Markdown supports the addition of HTML tags as needed to provide additional formatting. Note that HTML blocks will be processed as-is, which means that any Markdown-formatted content within the HTML block will be ignored.

Markdown doesn't support tables, but *HTML* does!

<table>
    <tr>
        <td>Hello</td>
        <td>World</td>
    </tr>
</table>

And now we're back into __Markdown__ again!

The example above produces the following HTML output once processed.

<p>Markdown doesn't support tables, but <em>HTML</em> does!</p>

<table>
    <tr>
        <td>Hello</td>
        <td>World</td>
    </tr>
</table>

<p>And now we're back into <strong>Markdown</strong> again!</p>

Creating a Documentation Website Using YUIDoc

Now we’ve written some documentation for our code, it’s time to surface this in an easy-to-use format for others to digest. We’ve been writing our documentation in YUIDoc format, so we’ll use the associated YUIDoc tool to generate us a site.

This YUIDoc tool is a JavaScript application designed to work with Node.js, an application framework that runs files written entirely in JavaScript on a command line. We’ll look in greater detail at Node.js in a future chapter but for now all you need to do is install it.

Visit http://bit.ly/node_js and download Node.js from there, following the instructions to install it; this also installs a tool called Node Package Manager (NPM) which allows you to quickly and easily download applications (known as packages) from a central repository.

Next we need to download the YUIDoc package itself. On the command line, execute the following command, which will automatically install the YUIDoc tool and make it available to run within any folder on your computer:

npm –g install yuidocjs

For those on a Mac or other Unix-based system, you may need to precede the command with sudo to allow the code to execute with sufficient privileges to install the tool system-wide.

Now we have YUIDoc installed, let’s run it. Use the command line to navigate to the folder containing your documented JavaScript code files and run the following command (without leaving off the period character at the end):

yuidoc .

When executed, YUIDoc will look through all the JavaScript files in the current folder and any sub folders within, and extract out the structured documentation from it. It will not attempt to execute any of your code, it merely reads each file as if it were plain text, looking for its specific set of tags and specially formatted opening comment block characters. It then takes the information it gleans from your documentation and generates a JSON-formatted file representing that data in a structured form, along with a full click-through HTML site generated using a default template style.

If you wish YUIDoc to only look in the current folder and no subfolders, supply the –n argument to the command.

yuidoc –n .

Now we can run YUIDoc to generate documentation for us, we need some code to generate the documentation for. Let’s use the code in Listing 2-5, which you should save into a file named Listing2-5.js within a folder on your computer. You can take a pre-written copy for youself from the code for this chapter hosted in GitHub at http://bit.ly/pro_js_dev. This code defines a parent “class” and a subclass, together with methods and properties, some public, some protected.

Listing 2-5. Documented code to use to generate a site using YUIDoc

/**
 * Accommodation-related "classes"
 *
 * @module Accommodation-related
 */

/**
 * A "class" defining types of accommodation
 *
 * @class Accommodation
 * @constructor
 * @example
 *     var myAccommodation = new Accommodation();
 */

var Accommodation = Class.create((function() {

    /**
     * Denotes whether the accommodation is currently locked
     *
     * @property {Boolean} _isLocked
     * @protected
     */

    var _isLocked = true,
        publicPropertiesAndMethods = {

            /**
             * Locks the accommodation
             *
             * @method lock
             * @example
             *     var myAccommodation = new Accommodation();
             *     myAccommodation.lock();
             */

            lock: function() {
                _isLocked = true;
            },

            /**
             * Unlocks the accommodation
             *
             * @method unlock
             * @example
             *     var myAccommodation = new Accommodation();
             *     myAccommodation.unlock();
             */

            unlock: function() {
                _isLocked = false;
            },

            /**
             * Establishes whether the accommodation is currently locked or not
             *
             * @method getIsLocked
             * @return {Boolean} Value indicating lock status—'true' means locked
             * @example
             *     var myAccommodation = new Accommodation();
             *     myAccommodation.getIsLocked(); // false
             *
             * @example
             *     var myAccommodation = new Accommodation();
             *     myAccommodation.lock();
             *     myAccommodation.getIsLocked(); // true
             */

            getIsLocked: function() {
                return _isLocked;
            },

            /**
             * Executed automatically upon creation of an object instance of this "class".
             * Unlocks the accommodation.
             *
             * @method initialize
             */

            initialize: function() {
                this.unlock();
            }
        };

    return publicPropertiesAndMethods;
}()));

/**
 * "Class" representing a house, a specific type of accommodation
 *
 * @class House
 * @constructor
 * @extends Accommodation
 * @example
 *     var myHouse = new House();
 */

var House = Accommodation.extend({

    /**
     * Indicates whether the house is alarmed or not—'true' means alarmed
     *
     * @property {Boolean} isAlarmed
     */

    isAlarmed: false,

    /**
     * Activates the house alarm
     *
     * @method alarm
     */

    alarm: function() {
        this.isAlarmed = true;
        alert("Alarm activated!");
    },

    /**
     * Locks the house and activates the alarm
     *
     * @method lock
     */

    lock: function() {
        Accommodation.prototype.lock.call(this);
        this.alarm();
    }
});——

Navigate to the folder you saved the code within from the command line, and execute YUIDoc to generate the documentation website for this code listing:

yuidoc –n .

This will have produced a subfolder named out within the current folder and filled it with HTML and CSS representing your documentation. Open the file named index.html in your web browser to view the generated website. This will reveal a page looking much like that shown in Figure 2-1.

9781430262688_Fig02-01.jpg

Figure 2-1. YUIDoc generates a full HTML site automatically from your documented JavaScript code

Two tabs on the left-hand side of the page allow you to jump between the lists of “classes” and modules that have been documented—we documented two “classes” and one module. Click on a module name to see a description of that module in the center of the page, together with a listing of all the “classes” grouped together into that module. Clicking on a “class” name here or in the left-hand side bar will display the full documentation for that “class” within the center area of the page.

The “class” documentation shows the “class” description together with the constructor function and the example code we declared within our documentation, complete with syntax highlighting. Three tabs beneath allow you to view an index list of all the methods and properties, or a detailed look at either the methods or the properties for that “class”. Clicking a method or property name takes you straight to the appropriate tab, scrolling the page to its definition and documentation. All the documentation from our code is here, formatted as easy-to-read text.

By default, the generated site only displays public properties and methods. To view or hide protected and private properties and methods, toggle the appropriate checkbox on the top-right of the page. When viewing the documentation for the House subclass, you can use the inherited checkbox on the top-right of the page to toggle between displaying all the methods and properties available to this “class,” or only those that were defined on the “class” definition itself. This can be a useful way of checking specific documentation for an inherited “class” or just viewing those methods and properties unique to that “class.”

Taking It Further

YUIDoc supports all sorts of customization, from setting the logo in the top-left of the page, to full prebuilt themes for an entirely different look to your documentation. To learn more about customizing YUIDoc, visit the project documentation page via http://bit.ly/yui_doc. For a good alternative theme, try Dana, available via http://bit.ly/yuidoc_dana. If you want to learn how to create your own custom themes, full documentation is available via http://bit.ly/yuidoc_themes. Have fun experimenting with YUIDoc and remember to make sure you document your code, both for the benefit of other developers and for your own sanity.

Summary

In this chapter, we’ve covered JavaScript code documentation, both casual and structured, which allow you to benefit yourself, your project team, and any members of the general public who interface with your code. We’ve covered YUIDoc and the Markdown format, and automatically produced a fully-fledged documentation website based on structured documentation in code without writing a single line of HTML or CSS.

In the next chapter, we will be looking into how to write the highest quality JavaScript code we can using a combination of tricks, tips and techniques, making our code run well and with as few errors as possible.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.17.174.156