Code coverage report for lib/toc.js

Statements: 100% (29 / 29)      Branches: 100% (15 / 15)      Functions: 100% (6 / 6)      Lines: 100% (27 / 27)      Ignored: none     

All files » lib/ » toc.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 1081                 1                 15 15 15 15 15                       87   87   84   84   83     83         83                 29                 14                   15   15                 83 3 3 1       82   82 12   70     82      
var EOL = require('os').EOL,
    inherit = require('inherit'),
    utils = require('./utils'),
    TOC_COMMENT = '<!-- TOC -->';
 
/**
 * @name Toc
 * @class
 */
module.exports = inherit({
    /**
     * Constructor
     * @param {String} source
     * @param {Object} [options]
     * @param {Number} [options.maxDepth]
     * @param {Char}   [options.bullet]
     */
    __constructor: function (source, options) {
        this.index = this._geIndex(source);
        this.data = '';
        this.options = options;
        this._cache = {};
        this._usedHeaders = [];
    },
 
    /**
     * Adds a TOC elemet
     * @param {Object} [header]
     * @param {Number} [header.depth]
     * @param {String} [header.text]
     * @returns {undefined}
     * @public
     */
    addTocElem: function (header, prevToken) {
        var options = this.options;
 
        if (header.depth > options.maxDepth) return;
 
        var headerText = utils.getHeader(header.text, prevToken);
 
        if (!headerText) return;
 
        var anchor = this._getAnchor(header.text, prevToken),
            indent = utils.getIndent(this._usedHeaders, header.depth);
 
        this._usedHeaders.unshift({
            depth: header.depth,
            indent: indent
        });
 
        this.data += indent + options.bullet + ' [' + headerText.replace(/\\/g, '\\\\') + '](#' + anchor + ')' + EOL;
    },
 
    /**
     * Returns an index of a TOC in a source
     * @returns {Number}
     * @public
     */
    getIndex: function () {
        return this.index;
    },
 
    /**
     * Returns a TOC data
     * @returns {String}
     * @public
     */
    getData: function () {
        return this.data;
    },
 
    /**
     * Returns an index of a TOC in a source
     * @param {String} source
     * @returns {Number}
     * @private
     */
    _geIndex: function (source) {
        var tocIndex = source.indexOf(TOC_COMMENT);
 
        return tocIndex !== -1  ? tocIndex + TOC_COMMENT.length : -1;
    },
 
    /**
     * Returns an anchor for a given header
     * @param {String} headerText
     * @returns {String}
     */
    _getAnchor: function (headerText, prevToken) {
        if (prevToken && prevToken.type === 'paragraph' && utils.isHtml(prevToken.text)) {
            var anchorFromHtml = utils.getAnchorFromHtml(prevToken.text);
            if (anchorFromHtml) {
                return anchorFromHtml;
            }
        }
 
        var anchor = utils.getAnchorFromHeader(headerText, prevToken);
 
        if (this._cache.hasOwnProperty(anchor)) {
            anchor += '-' + this._cache[anchor]++;
        } else {
            this._cache[anchor] = 1;
        }
 
        return anchor;
    }
});