├── docs └── index.html ├── .npmignore ├── scripts ├── genDoc └── changelog ├── .travis.yml ├── index.html ├── .gitignore ├── .jshintrc ├── LICENSE.md ├── lib ├── dir.js ├── option.js ├── parser.js ├── compiler.js ├── theme.js ├── symbol.js └── mr-doc.js ├── package.json ├── bin └── mr-doc ├── src ├── source maps │ ├── dir.js.map │ ├── option.js.map │ ├── parser.js.map │ ├── compiler.js.map │ ├── theme.js.map │ ├── symbol.js.map │ └── doxx.js.map ├── dir.js ├── option.js ├── parser.js ├── compiler.js ├── symbol.js ├── theme.js └── doxx.js ├── gulpfile.js ├── test └── symbol.test.js ├── README.md └── CHANGELOG.md /docs/index.html: -------------------------------------------------------------------------------- 1 |
Keyboard navigation
", 14 | "summary": "Keyboard navigation
", 15 | "body": "" 16 | }, 17 | "isPrivate": false, 18 | "ignore": false, 19 | "code": "keyboard: true," 20 | }; 21 | var mapped = Symbol.map(symbol); 22 | assert.deepEqual(mapped.type, "Boolean"); 23 | assert.deepEqual(mapped.type, "Boolean"); 24 | assert.deepEqual(mapped.gtype, undefined); 25 | assert.deepEqual(mapped['return'], undefined); 26 | }); 27 | }); 28 | describe('compact', function () { 29 | it('should compact correctly', function () { 30 | var symbol = { 31 | "tags": [{ 32 | "type": "description", 33 | "string": "a" 34 | }, 35 | { "type": "", "string": "b" }, 36 | { "type": "", "string": "c" }, 37 | { "type": "", "string": "d" }, 38 | { "type": "param", "name": "cl", "types": ["String"], "description": "a Css class" }, 39 | { 40 | "type": "param", 41 | "name": "options", 42 | "types": ["Object"], 43 | "description": "d" 44 | }, 45 | { "type": "", "string": "c" }, 46 | { "type": "", "string": "b" }, 47 | { "type": "", "string": "a" }, 48 | { 49 | "type": "type", 50 | "types": ["String"] 51 | }], 52 | "description": { 53 | "full": "Css class to add to the .popover element
", 54 | "summary": "Css class to add to the .popover element
", 55 | "body": "" 56 | }, 57 | "isPrivate": false, 58 | "ignore": false, 59 | "code": "addClass: \"\",", 60 | "ctx": {}, 61 | "type": "String" 62 | }; 63 | 64 | var compacted = Symbol.compact(symbol.tags); 65 | assert.equal(compacted.length, 4); 66 | assert.equal(compacted[0].string, "a b c d"); 67 | assert.equal(compacted[2].description, "d c b a"); 68 | }) 69 | }) 70 | }); 71 | // exports['._mapSymbol should add @description to .description full'] = function(t){ 72 | // var symbol = {"tags":[{"type":"description","string":"Note: if `addClass` is defined at the step level, the two defined `addClass` will be taken into account in the popover"},{"type":"type","types":["String"]}],"description":{"full":"Css class to add to the .popover element
","summary":"Css class to add to the .popover element
","body":""},"isPrivate":false,"ignore":false,"code":"addClass: \"\",","ctx":{},"type":"String"}; 73 | 74 | // var mapped = parser._mapSymbol(symbol); 75 | 76 | // t.deepEqual(mapped.description, "Boolean"); 77 | // t.deepEqual(mapped.gtype, undefined); 78 | // t.deepEqual(mapped['return'], undefined); 79 | 80 | // t.done(); 81 | // }; 82 | -------------------------------------------------------------------------------- /lib/parser.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import Symbol from './symbol'; 4 | import _ from 'lodash'; 5 | import path from 'path'; 6 | import Dir from './dir'; 7 | import dox from 'dox'; 8 | import File from 'fs-extra'; 9 | import 'source-map-support/register'; 10 | 11 | /** 12 | * The class that parses the dox tags. 13 | * @class Parser 14 | */ 15 | class Parser { 16 | constructor(options) { 17 | if (options) { 18 | this.options = options; 19 | this.start(); 20 | } 21 | } 22 | /** 23 | * Starts the parser. 24 | */ 25 | start() { 26 | var { 27 | source, extension, blacklist 28 | } = this.options; 29 | // Parse the files 30 | this.files = Parser.parse(source, extension, blacklist); 31 | } 32 | /** 33 | * Parses the source 34 | * @param {String|Array} source The source(s) to parse 35 | * @param {String} extension The file extension 36 | * @param {Array} ignore The files to ignore 37 | * @return {Array} The parsed files 38 | */ 39 | static parse(source, extension, ignore) { 40 | if (_.isArray(source)) { 41 | return source.map(doc => { 42 | var targetName = doc.name + '.' + extension; 43 | if (!doc.targetName) doc.targetName = targetName; 44 | doc.symbols = Symbol.structure(doc.dox, doc.targetName); 45 | return doc; 46 | }); 47 | } else { 48 | source = path.resolve(process.cwd(), source); 49 | let files = Dir.collectFiles(source, { 50 | ignore 51 | }); 52 | return files.map(file => { 53 | var dox = Parser.parseComments(path.join(source, file)); 54 | var targetName = file + '.' + extension; 55 | return { 56 | name: file.replace(/\\/g, '/'), 57 | targetName: targetName.replace(/\\/g, '/'), 58 | dox, 59 | symbols: Symbol.structure(dox, targetName) 60 | }; 61 | }); 62 | } 63 | } 64 | 65 | /** 66 | * Parses the source's comments using dox. 67 | * @param {string} filepath The path to the source 68 | * @return {object} Returns a JSON representation of the tags as an array 69 | * @jsFiddle https://jsfiddle.net/iwatakeshi/8hc50sbc/embedded/ 70 | */ 71 | static parseComments(filepath) { 72 | var json = null; 73 | try { 74 | json = dox.parseComments(File.readFileSync(filepath).toString(), { 75 | raw: false 76 | }); 77 | } catch (error) { 78 | console.error('Doxx [error]:', error); 79 | return []; 80 | } 81 | 82 | return json.filter(Parser.shouldPass).map(Symbol.map); 83 | } 84 | /** 85 | * Tests if a symbol should be ignored or not. 86 | * @param {Object} symbol symbol to check against 87 | * @return {Boolean} true if the symbol is not private nor must be ignored 88 | */ 89 | static shouldPass(symbol) { 90 | if (symbol.isPrivate) { 91 | return false; 92 | } 93 | if (symbol.ignore) { 94 | return false; 95 | } 96 | 97 | // Only for coffeescript 98 | return symbol.tags.filter(function (tag) { 99 | return tag.type === 'private' || tag.type === 'ignore'; 100 | }).length === 0; 101 | } 102 | } 103 | 104 | export default Parser; -------------------------------------------------------------------------------- /src/dir.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, '__esModule', { 4 | value: true 5 | }); 6 | 7 | var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); 8 | 9 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 10 | 11 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 12 | 13 | var _path = require('path'); 14 | 15 | var _path2 = _interopRequireDefault(_path); 16 | 17 | var _walkdir = require('walkdir'); 18 | 19 | var _walkdir2 = _interopRequireDefault(_walkdir); 20 | 21 | var _lodash = require('lodash'); 22 | 23 | var _lodash2 = _interopRequireDefault(_lodash); 24 | 25 | var _osenv = require('osenv'); 26 | 27 | var _osenv2 = _interopRequireDefault(_osenv); 28 | 29 | var _fs = require('fs'); 30 | 31 | var _fs2 = _interopRequireDefault(_fs); 32 | 33 | require('source-map-support/register'); 34 | 35 | /** 36 | * The class that manages directories. 37 | * @class Dir 38 | */ 39 | 40 | var Dir = (function () { 41 | function Dir() { 42 | _classCallCheck(this, Dir); 43 | } 44 | 45 | /** 46 | * Create an array of all the right files in the source dir 47 | * @param {String} source source path 48 | * @param {Object} options option object 49 | * @return {Array} 50 | */ 51 | 52 | _createClass(Dir, null, [{ 53 | key: 'collectFiles', 54 | value: function collectFiles(source, options) { 55 | var dirtyFiles = _walkdir2['default'].sync(source), 56 | // tee hee! 57 | ignore = options.ignore || [], 58 | files = []; 59 | dirtyFiles.forEach(function (file) { 60 | file = _path2['default'].relative(source, file); 61 | var doNotIgnore = _lodash2['default'].all(ignore, function (d) { 62 | // return true if no part of the path is in the ignore/black list 63 | return file.indexOf(d) === -1; 64 | }); 65 | 66 | if (file.substr(-2) === 'js' && doNotIgnore) { 67 | files.push(file); 68 | } 69 | }); 70 | 71 | return files; 72 | } 73 | 74 | /** 75 | * Locates the home directory for the 76 | * current operating system. 77 | * Credits to @cliftonc 78 | * @return {String} The home directory path 79 | */ 80 | }, { 81 | key: 'getHomeDir', 82 | value: function getHomeDir() { 83 | return _osenv2['default'].home() || process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE; 84 | } 85 | 86 | /** 87 | * Checks if the directory exists 88 | * @param {String} path The path to the directory 89 | * @return {Boolean} The truth value 90 | */ 91 | }, { 92 | key: 'exists', 93 | value: function exists(path) { 94 | try { 95 | _fs2['default'].statSync(path); 96 | return true; 97 | } catch (err) { 98 | return !(err && err.code === 'ENOENT'); 99 | } 100 | } 101 | }]); 102 | 103 | return Dir; 104 | })(); 105 | 106 | exports['default'] = Dir; 107 | module.exports = exports['default']; 108 | //# sourceMappingURL=source maps/dir.js.map -------------------------------------------------------------------------------- /lib/compiler.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import jade from 'jade'; 4 | import File from 'fs'; 5 | import Path from 'path'; 6 | import _ from 'lodash'; 7 | import 'source-map-support/register'; 8 | /** 9 | * The class that compiles the Jade template. 10 | * @class Compiler 11 | */ 12 | class Compiler { 13 | constructor(parser) { 14 | 15 | /** 16 | * Jade used to compile the documentation 17 | * @type {Jade} Jade compiler 18 | */ 19 | this.jade = jade; 20 | 21 | // Set the options 22 | this.options = parser ? parser.options : {}; 23 | // Sets the files from the parser 24 | this.files = parser ? parser.files : []; 25 | // Set up the compiler's code filter 26 | this.setCodeFilter(); 27 | } 28 | /** 29 | * Compiles the docs 30 | * @param {Object} locals The local variable object 31 | * @param {String} template The template to compile 32 | * @jsFiddle https://jsfiddle.net/iwatakeshi/pmp9ygwL/embedded/ 33 | * @return {String} The compiled content 34 | */ 35 | compile(locals, template) { 36 | // Get the path (alias for filename) 37 | var { 38 | path 39 | } = this.options.template; 40 | // Return the compiled template 41 | return this.jade.compile(template || this.template, { 42 | pretty: true, 43 | filename: path 44 | })(locals); 45 | } 46 | /** 47 | * Compiles the docs with a specified path 48 | * @param {Object} path The path to compile 49 | * @param {Object} locals The local variable object 50 | * @param {String} template The template to compile 51 | * @return {String} The compiled content 52 | */ 53 | compileWithPath(path, locals, template) { 54 | // Return the compiled template 55 | return this.jade.compile(template || this.template, { 56 | pretty: true, 57 | // Alias for filename 58 | filename: path 59 | })(locals); 60 | } 61 | /** 62 | * Sets the template 63 | * @param {String} template The template 64 | * @returns {Compiler} The compiler 65 | */ 66 | setTemplate(template) { 67 | // Template used to produce the documentation 68 | this.template = template; 69 | return this; 70 | } 71 | 72 | /** 73 | * Sets the template 74 | * @param {String} path The path to the template 75 | * @returns {Compiler} The compiler 76 | */ 77 | setTemplateWithPath(path) { 78 | // Template used to produce the documentation 79 | this.template = File.readFileSync( 80 | Path.resolve(__dirname, path || 81 | this.options.template.path)).toString(); 82 | return this; 83 | } 84 | 85 | /** 86 | * Sets custom filter(s) 87 | * @param {Array|Object} filters The custom filter(s) to set 88 | * @jsFiddle https://jsfiddle.net/iwatakeshi/sbr206cf/embedded/ 89 | * @returns {Compiler} The compiler 90 | */ 91 | setFilters(filters) { 92 | // Check if the fitlers is an object 93 | if (_.isPlainObject(filters)) { 94 | this.jade.filters[filters.name] = filters.filter; 95 | } 96 | // Check if the filters is an array 97 | if (_.isArray(filters)) { 98 | _.forEach(filters, (filter) => { 99 | this.jade.filters[filter.name] = filter.filter; 100 | }); 101 | } 102 | return this; 103 | } 104 | 105 | /** 106 | * Sets the code filter for `:code` 107 | * @param {Function} filter The code filter to set 108 | * @returns {Compiler} The compiler 109 | */ 110 | setCodeFilter(filter) { 111 | /** 112 | * Jade support for filter `:code` 113 | * @param {String} block 114 | * @return {String} 115 | */ 116 | this.jade.filters.code = filter || function (block) { 117 | return block.replace(/&/g, '&') 118 | .replace(//g, '>') 120 | .replace(/"/g, '"') 121 | .replace(/#/g, '#') 122 | .replace(/\\/g, '\\\\') 123 | .replace(/\n/g, '\\n'); 124 | }; 125 | 126 | return this; 127 | } 128 | } 129 | 130 | export 131 | default Compiler; -------------------------------------------------------------------------------- /src/source maps/option.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["option.js"],"names":[],"mappings":"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","file":"option.js","sourcesContent":["/*! global __dirname, process */\n\n'use strict';\n\nimport path from 'path';\nimport _ from 'lodash';\nimport 'source-map-support/register';\n\n/**\n * The class that sets the options.\n * @class Option\n */\nclass Option {\n constructor(options) {\n this.options = this.getDefaults();\n if (options) this.setOptions(options);\n }\n /**\n * Sets the options\n */\n setOptions(options) {\n\n if (options.title) {\n this.options.title = options.title;\n }\n\n if (options.extension) {\n this.options.extension = options.extension;\n }\n\n if (options.template) {\n this.options.template.path = options.template;\n }\n\n if (!options.source) {\n console.error(new Error('Doxx [error]: You must define a source.'));\n process.exit(1);\n } else\n this.options.source = options.source;\n\n if (options.target) {\n this.options.target = path.resolve(process.cwd(), options.target) ||\n process.cwd();\n }\n if (options.ignore) {\n this.options.blacklist = options.ignore\n .trim().replace(' ', '').split(',');\n }\n\n if (options.readme) {\n this.options.readme = options.readme;\n }\n\n if (options.theme) {\n if (_.isString(options.theme) && !_.isEmpty(options.theme)) {\n this.options.theme =\n options.theme.indexOf('doxx-theme-') > -1 ? options.theme :\n 'doxx-theme-' + options.theme;\n } else this.options.theme = 'doxx-theme-default';\n }\n }\n /**\n * Returns the current options.\n * @return {object} The current options\n */\n getOptions() {\n return this.options;\n }\n /**\n * Returns the default options.\n * @return {object} The default options\n */\n getDefaults() {\n return {\n // The title for the page produced\n 'title': undefined,\n // The folder which should get parsed\n 'source': '',\n // The folder which will contain the results.\n 'target': '',\n // The target files extension.\n 'extension': 'html',\n // The comma seperated list of directories to ignore. (alias for ignore)\n 'blacklist': [\n 'test', 'public', 'static', 'view',\n 'views', 'template', 'templates'\n ],\n // The markdown file to use on the main page of the documentations. \n // Checks the current directory for a package.json or README.md by default\n 'readme': '',\n 'package': undefined,\n 'template': {\n 'path': undefined\n },\n 'theme': 'doxx-theme-default'\n };\n }\n}\n\nexport default (options) => {\n return new Option(options);\n};"],"sourceRoot":"/source/"} -------------------------------------------------------------------------------- /src/option.js: -------------------------------------------------------------------------------- 1 | /*! global __dirname, process */ 2 | 3 | 'use strict'; 4 | 5 | Object.defineProperty(exports, '__esModule', { 6 | value: true 7 | }); 8 | 9 | var _createClass = (function () { 10 | function defineProperties(target, props) { 11 | for (var i = 0; i < props.length; i++) { 12 | var descriptor = props[i]; 13 | descriptor.enumerable = descriptor.enumerable || false; 14 | descriptor.configurable = true; 15 | if ('value' in descriptor) descriptor.writable = true; 16 | Object.defineProperty(target, descriptor.key, descriptor); 17 | } 18 | } 19 | return function (Constructor, protoProps, staticProps) { 20 | if (protoProps) defineProperties(Constructor.prototype, protoProps); 21 | if (staticProps) defineProperties(Constructor, staticProps); 22 | return Constructor; 23 | }; 24 | })(); 25 | 26 | function _interopRequireDefault(obj) { 27 | return obj && obj.__esModule ? obj : { 28 | 'default': obj 29 | }; 30 | } 31 | 32 | function _classCallCheck(instance, Constructor) { 33 | if (!(instance instanceof Constructor)) { 34 | throw new TypeError('Cannot call a class as a function'); 35 | } 36 | } 37 | 38 | var _path = require('path'); 39 | 40 | var _path2 = _interopRequireDefault(_path); 41 | 42 | var _lodash = require('lodash'); 43 | 44 | var _lodash2 = _interopRequireDefault(_lodash); 45 | 46 | require('source-map-support/register'); 47 | 48 | /** 49 | * The class that sets the options. 50 | * @class Option 51 | */ 52 | 53 | var Option = (function () { 54 | function Option(options) { 55 | _classCallCheck(this, Option); 56 | 57 | this.options = this.getDefaults(); 58 | if (options) this.setOptions(options); 59 | } 60 | 61 | /** 62 | * Sets the options 63 | */ 64 | 65 | _createClass(Option, [{ 66 | key: 'setOptions', 67 | value: function setOptions(options) { 68 | 69 | if (options.title) { 70 | this.options.title = options.title; 71 | } 72 | 73 | if (options.extension) { 74 | this.options.extension = options.extension; 75 | } 76 | 77 | if (options.template) { 78 | this.options.template.path = options.template; 79 | } 80 | 81 | if (!options.source) { 82 | console.error(new Error('Doxx [error]: You must define a source.')); 83 | process.exit(1); 84 | } else this.options.source = options.source; 85 | 86 | if (options.target) { 87 | this.options.target = _path2['default'].resolve(process.cwd(), options.target) || process.cwd(); 88 | } 89 | if (options.ignore) { 90 | this.options.blacklist = options.ignore.trim().replace(' ', '').split(','); 91 | } 92 | 93 | if (options.readme) { 94 | this.options.readme = options.readme; 95 | } 96 | 97 | if (options.theme) { 98 | if (_lodash2['default'].isString(options.theme) && !_lodash2['default'].isEmpty(options.theme)) { 99 | this.options.theme = options.theme.indexOf('mr-doc-theme-') > -1 ? options.theme : 'mr-doc-theme-' + options.theme; 100 | } else this.options.theme = 'mr-doc-theme-default'; 101 | } 102 | } 103 | 104 | /** 105 | * Returns the current options. 106 | * @return {object} The current options 107 | */ 108 | }, { 109 | key: 'getOptions', 110 | value: function getOptions() { 111 | return this.options; 112 | } 113 | 114 | /** 115 | * Returns the default options. 116 | * @return {object} The default options 117 | */ 118 | }, { 119 | key: 'getDefaults', 120 | value: function getDefaults() { 121 | return { 122 | // The title for the page produced 123 | 'title': undefined, 124 | // The folder which should get parsed 125 | 'source': '', 126 | // The folder which will contain the results. 127 | 'target': '', 128 | // The target files extension. 129 | 'extension': 'html', 130 | // The comma seperated list of directories to ignore. (alias for ignore) 131 | 'blacklist': ['test', 'public', 'static', 'view', 'views', 'template', 'templates'], 132 | // The markdown file to use on the main page of the documentations. 133 | // Checks the current directory for a package.json or README.md by default 134 | 'readme': '', 135 | 'package': undefined, 136 | 'template': { 137 | 'path': undefined 138 | }, 139 | 'theme': 'mr-doc-theme-default' 140 | }; 141 | } 142 | }]); 143 | 144 | return Option; 145 | })(); 146 | 147 | exports['default'] = function (options) { 148 | return new Option(options); 149 | }; 150 | 151 | module.exports = exports['default']; 152 | //# sourceMappingURL=source maps/option.js.map 153 | -------------------------------------------------------------------------------- /src/source maps/parser.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["parser.js"],"names":[],"mappings":"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","file":"parser.js","sourcesContent":["'use strict';\n\nimport Symbol from './symbol';\nimport _ from 'lodash';\nimport path from 'path';\nimport Dir from './dir';\nimport dox from 'dox';\nimport File from 'fs-extra';\nimport 'source-map-support/register';\n\n/**\n * The class that parses the dox tags.\n * @class Parser\n */\nclass Parser {\n constructor(options) {\n if (options) {\n this.options = options;\n this.start();\n }\n }\n /**\n * Starts the parser.\n */\n start() {\n var {\n source, extension, blacklist\n } = this.options;\n // Parse the files\n this.files = Parser.parse(source, extension, blacklist);\n }\n /**\n * Parses the source\n * @param {String|Array} source The source(s) to parse\n * @param {String} extension The file extension\n * @param {Array} ignore The files to ignore\n * @return {Array} The parsed files\n */\n static parse(source, extension, ignore) {\n if (_.isArray(source)) {\n return source.map(doc => {\n var targetName = doc.name + '.' + extension;\n if (!doc.targetName) doc.targetName = targetName;\n doc.symbols = Symbol.structure(doc.dox, doc.targetName);\n return doc;\n });\n } else {\n source = path.resolve(process.cwd(), source);\n let files = Dir.collectFiles(source, {\n ignore\n });\n return files.map(file => {\n var dox = Parser.parseComments(path.join(source, file));\n var targetName = file + '.' + extension;\n return {\n name: file.replace(/\\\\/g, '/'),\n targetName: targetName.replace(/\\\\/g, '/'),\n dox,\n symbols: Symbol.structure(dox, targetName)\n };\n });\n }\n }\n\n /**\n * Parses the source's comments using dox.\n * @param {string} filepath The path to the source \n * @return {object} Returns a JSON representation of the tags as an array\n * @jsFiddle https://jsfiddle.net/iwatakeshi/8hc50sbc/embedded/\n */\n static parseComments(filepath) {\n var json = null;\n try {\n json = dox.parseComments(File.readFileSync(filepath).toString(), {\n raw: false\n });\n } catch (error) {\n console.error('Doxx [error]:', error);\n return [];\n }\n\n return json.filter(Parser.shouldPass).map(Symbol.map);\n }\n /**\n * Tests if a symbol should be ignored or not.\n * @param {Object} symbol symbol to check against\n * @return {Boolean} true if the symbol is not private nor must be ignored\n */\n static shouldPass(symbol) {\n if (symbol.isPrivate) {\n return false;\n }\n if (symbol.ignore) {\n return false;\n }\n\n // Only for coffeescript\n return symbol.tags.filter(function (tag) {\n return tag.type === 'private' || tag.type === 'ignore';\n }).length === 0;\n }\n}\n\nexport default Parser;"],"sourceRoot":"/source/"} -------------------------------------------------------------------------------- /lib/theme.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | import when from 'when'; 3 | import Path from 'path'; 4 | import _ from 'lodash'; 5 | import fs from 'fs'; 6 | import File from 'fs-extra'; 7 | import elegantSpinner from 'elegant-spinner'; 8 | import logUpdate from 'log-update'; 9 | import 'source-map-support/register'; 10 | 11 | let frame = elegantSpinner(); 12 | 13 | /** 14 | * The class that locates themes 15 | * @class Theme 16 | */ 17 | class Theme { 18 | constructor(options) { 19 | 20 | let resolved = { 21 | theme: this.locateTheme(options.theme) 22 | }; 23 | 24 | this.options = { 25 | theme: { 26 | name: resolved.theme.name, 27 | path: resolved.theme.path 28 | }, 29 | target: { 30 | path: options.target 31 | } 32 | }; 33 | 34 | } 35 | 36 | /** 37 | * Find the theme specified 38 | */ 39 | locateTheme(theme) { 40 | 41 | const DEFAULT_THEME = 'mr-doc-theme-default'; 42 | 43 | const mrDocPath = Path.resolve(__dirname, '..'); 44 | const projectPath = process.cwd(); 45 | 46 | const locations = { 47 | project: Path.join(projectPath, 48 | 'node_modules', 49 | theme), 50 | mrDoc: Path.join(mrDocPath, 51 | 'node_modules', 52 | theme), 53 | default: Path.join(mrDocPath, 54 | 'node_modules', 55 | DEFAULT_THEME) 56 | }; 57 | 58 | 59 | let exists = fs.existsSync(locations.mrDoc); 60 | if (exists) { 61 | console.log('mr-doc [info]: Using theme [' + theme + ']'); 62 | return { 63 | name: theme, 64 | path: locations.mrDoc 65 | }; 66 | } 67 | 68 | exists = fs.existsSync(locations.project); 69 | if (exists) { 70 | console.log('mr-doc [info]: Using theme [' + theme + ']'); 71 | return { 72 | name: theme, 73 | path: locations.project 74 | }; 75 | } 76 | 77 | console.log('mr-doc [warning]: theme "' + 78 | theme + 79 | '" not found, reverting to default.'); 80 | 81 | return { 82 | name: DEFAULT_THEME, 83 | path: locations.default 84 | }; 85 | 86 | } 87 | 88 | /** 89 | * Copies the theme specified (reverting to default) 90 | * over to the target directory. 91 | */ 92 | static configure(options) { 93 | 94 | let final = when.defer(); 95 | 96 | // Sources 97 | let config = { 98 | src: options.theme.path, 99 | dest: options.target.path, 100 | paths: { 101 | css: { 102 | src: 'assets/css', 103 | dest: 'css' 104 | }, 105 | js: { 106 | src: 'assets/js', 107 | dest: 'js' 108 | } 109 | } 110 | }; 111 | 112 | /** 113 | * The commands to install the theme 114 | * @type {object} 115 | */ 116 | let commands = { 117 | showProgress: (command) => { 118 | var count = 0; 119 | while (count < 200) { 120 | logUpdate('mr-doc [info]: ' + frame() + ' ' + command); 121 | count++; 122 | } 123 | }, 124 | /** 125 | * Create necessary paths to destination folder 126 | */ 127 | copyAssets: () => { 128 | let types = _.keys(config.paths); 129 | let m = when.map(types, function (type) { 130 | let d = when.defer(); 131 | let src = Path.join(config.src, config.paths[type].src); 132 | let dest = Path.join(config.dest, config.paths[type].dest); 133 | File.copy(src, dest, { 134 | clobber: true 135 | }, error => { 136 | if (error) d.reject(error); 137 | else { 138 | d.resolve(); 139 | } 140 | }); 141 | return d.promise; 142 | }); 143 | return m; 144 | }, 145 | /** 146 | * Reads the template from the source and strigifies it. 147 | */ 148 | stringifyTemplate: () => { 149 | let d = when.defer(); 150 | let file = Path.join(config.src, 'template/index.jade'); 151 | File.readFile(file, (error, data) => { 152 | if (error) d.reject(error); 153 | else d.resolve({ 154 | template: data.toString() 155 | }); 156 | }); 157 | return d.promise; 158 | } 159 | }; 160 | 161 | // Check if the template is enabled (legacy) 162 | if (options.template && options.template.path) { 163 | final.resolve({ 164 | template: File.readFileSync( 165 | Path.resolve(__dirname, 166 | options.template.path)).toString() 167 | }); 168 | } else { 169 | (() => { 170 | return commands.copyAssets() 171 | .then(commands.stringifyTemplate) 172 | .then(final.resolve); 173 | })(commands.showProgress); 174 | } 175 | return final.promise; 176 | } 177 | /** 178 | * Copies the specific theme assets over to the target directory 179 | * and returns the 180 | */ 181 | install() { 182 | return Theme.configure(this.options); 183 | } 184 | } 185 | 186 | export default Theme; 187 | -------------------------------------------------------------------------------- /src/parser.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, '__esModule', { 4 | value: true 5 | }); 6 | 7 | var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); 8 | 9 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 10 | 11 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 12 | 13 | var _symbol = require('./symbol'); 14 | 15 | var _symbol2 = _interopRequireDefault(_symbol); 16 | 17 | var _lodash = require('lodash'); 18 | 19 | var _lodash2 = _interopRequireDefault(_lodash); 20 | 21 | var _path = require('path'); 22 | 23 | var _path2 = _interopRequireDefault(_path); 24 | 25 | var _dir = require('./dir'); 26 | 27 | var _dir2 = _interopRequireDefault(_dir); 28 | 29 | var _dox = require('dox'); 30 | 31 | var _dox2 = _interopRequireDefault(_dox); 32 | 33 | var _fsExtra = require('fs-extra'); 34 | 35 | var _fsExtra2 = _interopRequireDefault(_fsExtra); 36 | 37 | require('source-map-support/register'); 38 | 39 | /** 40 | * The class that parses the dox tags. 41 | * @class Parser 42 | */ 43 | 44 | var Parser = (function () { 45 | function Parser(options) { 46 | _classCallCheck(this, Parser); 47 | 48 | if (options) { 49 | this.options = options; 50 | this.start(); 51 | } 52 | } 53 | 54 | /** 55 | * Starts the parser. 56 | */ 57 | 58 | _createClass(Parser, [{ 59 | key: 'start', 60 | value: function start() { 61 | var _options = this.options; 62 | var source = _options.source; 63 | var extension = _options.extension; 64 | var blacklist = _options.blacklist; 65 | 66 | // Parse the files 67 | this.files = Parser.parse(source, extension, blacklist); 68 | } 69 | 70 | /** 71 | * Parses the source 72 | * @param {String|Array} source The source(s) to parse 73 | * @param {String} extension The file extension 74 | * @param {Array} ignore The files to ignore 75 | * @return {Array} The parsed files 76 | */ 77 | }], [{ 78 | key: 'parse', 79 | value: function parse(source, extension, ignore) { 80 | if (_lodash2['default'].isArray(source)) { 81 | return source.map(function (doc) { 82 | var targetName = doc.name + '.' + extension; 83 | if (!doc.targetName) doc.targetName = targetName; 84 | doc.symbols = _symbol2['default'].structure(doc.dox, doc.targetName); 85 | return doc; 86 | }); 87 | } else { 88 | source = _path2['default'].resolve(process.cwd(), source); 89 | var files = _dir2['default'].collectFiles(source, { 90 | ignore: ignore 91 | }); 92 | return files.map(function (file) { 93 | var dox = Parser.parseComments(_path2['default'].join(source, file)); 94 | var targetName = file + '.' + extension; 95 | return { 96 | name: file.replace(/\\/g, '/'), 97 | targetName: targetName.replace(/\\/g, '/'), 98 | dox: dox, 99 | symbols: _symbol2['default'].structure(dox, targetName) 100 | }; 101 | }); 102 | } 103 | } 104 | 105 | /** 106 | * Parses the source's comments using dox. 107 | * @param {string} filepath The path to the source 108 | * @return {object} Returns a JSON representation of the tags as an array 109 | * @jsFiddle https://jsfiddle.net/iwatakeshi/8hc50sbc/embedded/ 110 | */ 111 | }, { 112 | key: 'parseComments', 113 | value: function parseComments(filepath) { 114 | var json = null; 115 | try { 116 | json = _dox2['default'].parseComments(_fsExtra2['default'].readFileSync(filepath).toString(), { 117 | raw: false 118 | }); 119 | } catch (error) { 120 | console.error('Doxx [error]:', error); 121 | return []; 122 | } 123 | 124 | return json.filter(Parser.shouldPass).map(_symbol2['default'].map); 125 | } 126 | 127 | /** 128 | * Tests if a symbol should be ignored or not. 129 | * @param {Object} symbol symbol to check against 130 | * @return {Boolean} true if the symbol is not private nor must be ignored 131 | */ 132 | }, { 133 | key: 'shouldPass', 134 | value: function shouldPass(symbol) { 135 | if (symbol.isPrivate) { 136 | return false; 137 | } 138 | if (symbol.ignore) { 139 | return false; 140 | } 141 | 142 | // Only for coffeescript 143 | return symbol.tags.filter(function (tag) { 144 | return tag.type === 'private' || tag.type === 'ignore'; 145 | }).length === 0; 146 | } 147 | }]); 148 | 149 | return Parser; 150 | })(); 151 | 152 | exports['default'] = Parser; 153 | module.exports = exports['default']; 154 | //# sourceMappingURL=source maps/parser.js.map -------------------------------------------------------------------------------- /lib/symbol.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import _ from 'lodash'; 4 | import 'source-map-support/register'; 5 | 6 | /** 7 | * The class that manges symbols. 8 | * @class Symbol 9 | */ 10 | class Symbol { 11 | constructor() {} 12 | /** 13 | * Returns the structure of a parsed file 14 | * @param {Array} symbols array of symbols 15 | * @param {String} file filename 16 | * @return {Array} 17 | */ 18 | static structure(symbols, file) { 19 | return _.compact(symbols.map(function (method) { 20 | if (!method.ctx || !method.ctx.name) { 21 | return null; 22 | } 23 | return { 24 | targetFile: file, 25 | name: method.ctx.name, 26 | type: method.ctx.type 27 | }; 28 | })) || []; 29 | } 30 | /** 31 | * Checks if a tag has a specific type 32 | * @param {string} val value to check against 33 | * @return {function} A function that evaluates the truth 34 | * when True if `tag` type is `val` 35 | */ 36 | static has(val) { 37 | return function (tag) { 38 | return tag.type === val; 39 | }; 40 | } 41 | /** 42 | * Compacts multi-line expression 43 | * @return {Array} 44 | */ 45 | static compact(tags) { 46 | 47 | // [{"type":"description", 48 | // "string":"Note: if `addClass` is defined at the step level."}, 49 | // {"type":"", 50 | // "string": "The two defined `addClass` 51 | // will be taken into account in the popover"}, 52 | // {"type":"type","types":["String"]}] 53 | var compacted = []; 54 | 55 | tags.forEach(function (tag, i) { 56 | if (!tag.type) { 57 | if (i === 0) { 58 | return; 59 | } 60 | // Append to previous 61 | var prevTag = compacted[compacted.length - 1]; 62 | if (prevTag.description) { 63 | prevTag.description += ' ' + tag.string; 64 | } else { 65 | prevTag.string += ' ' + tag.string; 66 | } 67 | return; 68 | } 69 | 70 | compacted.push(tag); 71 | }); 72 | 73 | return compacted; 74 | } 75 | 76 | /** 77 | * Maps symbols 78 | * @private 79 | * @param {Object} symbol 80 | * @return {Object} 81 | */ 82 | static map(symbol) { 83 | symbol.tags = Symbol.compact(symbol.tags); 84 | var tags = {}; 85 | ['type', 'description', 'example', 'file', 'fileoverview', 86 | 'overview', 'param', 'require', 87 | 'jsfiddle', 'jsFiddle', 'JSFiddle', 88 | 'return', 'returns' 89 | ].forEach(tag => { 90 | // Handle special cases 91 | if (tag.match(/(return|returns)\b/)) 92 | tags.returns = symbol.tags.filter((s) => { 93 | return Symbol.has('return')(s) || 94 | Symbol.has('returns')(s); 95 | }); 96 | else if (tag.match(/(jsfiddle|jsFiddle|JSFiddle)\b/)) { 97 | tags.jsfiddles = symbol.tags.filter((s) => { 98 | return Symbol.has('jsfiddle')(s) || 99 | Symbol.has('jsFiddle')(s) || 100 | Symbol.has('JSFiddle')(s); 101 | }); 102 | } else tags[tag.toLowerCase() + 's'] = 103 | symbol.tags.filter(Symbol.has(tag)); 104 | }); 105 | var { 106 | types, descriptions, examples, files, fileoverviews, 107 | overviews, returns, requires, jsfiddles 108 | } = tags; 109 | if (symbol.tags.length > 0 && 110 | symbol.tags.filter(Symbol.has('param')).length > 0) { 111 | 112 | symbol.hasParams = true; 113 | } 114 | 115 | if (!symbol.ctx) { 116 | symbol.ctx = {}; 117 | } 118 | 119 | if (symbol.ctx.type) { 120 | symbol.gtype = symbol.ctx.type; 121 | } 122 | 123 | if (types.length === 1) { 124 | symbol.type = types[0].types.join(' | '); 125 | } 126 | 127 | if (files.length === 1) { 128 | symbol.file = files[0].type; 129 | symbol.fileString = files[0].string; 130 | symbol.fileHtml = files[0].html; 131 | } 132 | 133 | if (fileoverviews.length === 1) { 134 | symbol.files = fileoverviews[0].type; 135 | symbol.fileString = fileoverviews[0].string; 136 | symbol.fileHtml = fileoverviews[0].html; 137 | } 138 | 139 | if (overviews.length === 1) { 140 | symbol.files = overviews[0].type; 141 | symbol.fileString = overviews[0].string; 142 | symbol.fileHtml = overviews[0].html; 143 | } 144 | 145 | if (returns.length !== 0) { 146 | symbol.returns = []; 147 | returns.forEach(function (returned) { 148 | symbol.returns.push(returned); 149 | }); 150 | } 151 | 152 | if (examples.length !== 0) { 153 | symbol.examples = []; 154 | examples.forEach(function (example) { 155 | symbol.examples.push(example.string); 156 | }); 157 | } 158 | 159 | if (requires.length !== 0) { 160 | symbol.requires = []; 161 | requires.forEach(function (required) { 162 | symbol.requires.push(required.string); 163 | }); 164 | } 165 | 166 | // No idea what this is for but it's there anyways. 167 | symbol.description.extra = ''; 168 | if (descriptions.length === 1) { 169 | symbol.description.extra = '' + descriptions[0].string + '
'; 170 | } 171 | 172 | if (jsfiddles.length === 1) { 173 | symbol.jsfiddle = jsfiddles[0].string; 174 | } 175 | 176 | return symbol; 177 | } 178 | } 179 | 180 | export default Symbol; -------------------------------------------------------------------------------- /src/source maps/compiler.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["compiler.js"],"names":[],"mappings":"AAAA,YAAY,CAAC;;;;;;;;;;;;oBAEI,MAAM;;;;kBACN,IAAI;;;;oBACJ,MAAM;;;;sBACT,QAAQ;;;;QACf,6BAA6B;;;;;;;IAK9B,QAAQ;AACD,WADP,QAAQ,CACA,MAAM,EAAE;0BADhB,QAAQ;;;;;;AAOR,QAAI,CAAC,IAAI,oBAAO,CAAC;;;AAGjB,QAAI,CAAC,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC,OAAO,GAAG,EAAE,CAAC;;AAE5C,QAAI,CAAC,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC,KAAK,GAAG,EAAE,CAAC;;AAExC,QAAI,CAAC,aAAa,EAAE,CAAC;GACtB;;;;;;;;;;eAfC,QAAQ;;WAuBL,iBAAC,MAAM,EAAE,QAAQ,EAAE;;UAGpB,IAAI,GACF,IAAI,CAAC,OAAO,CAAC,QAAQ,CADvB,IAAI;;;AAGN,aAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,EAAE;AAClD,cAAM,EAAE,IAAI;AACZ,gBAAQ,EAAE,IAAI;OACf,CAAC,CAAC,MAAM,CAAC,CAAC;KACZ;;;;;;;;;;;WAQY,yBAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE;;AAEpC,aAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,EAAE;AAClD,cAAM,EAAE,IAAI;;AAEZ,gBAAQ,EAAE,IAAI;OACf,CAAC,CAAC,MAAM,CAAC,CAAC;KACZ;;;;;;;;;WAMQ,qBAAC,QAAQ,EAAE;;AAEpB,UAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;AACzB,aAAO,IAAI,CAAC;KACb;;;;;;;;;WAOkB,6BAAC,IAAI,EAAE;;AAExB,UAAI,CAAC,QAAQ,GAAG,gBAAK,YAAY,CAC/B,kBAAK,OAAO,CAAC,SAAS,EAAE,IAAI,IAC1B,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;AAC5C,aAAO,IAAI,CAAC;KACb;;;;;;;;;;WAQS,oBAAC,OAAO,EAAE;;;;AAElB,UAAI,oBAAE,aAAa,CAAC,OAAO,CAAC,EAAE;AAC5B,YAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;OAClD;;AAED,UAAI,oBAAE,OAAO,CAAC,OAAO,CAAC,EAAE;AACtB,4BAAE,OAAO,CAAC,OAAO,EAAE,UAAC,MAAM,EAAK;AAC7B,gBAAK,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC;SAChD,CAAC,CAAC;OACJ;AACD,aAAO,IAAI,CAAC;KACb;;;;;;;;;WAOY,uBAAC,MAAM,EAAE;;;;;;AAMpB,UAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,GAAG,MAAM,IAAI,UAAU,KAAK,EAAE;AAClD,eAAO,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAChC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC,CACvB,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CACtB,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CACtB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;OAC1B,CAAC;;AAEF,aAAO,IAAI,CAAC;KACb;;;SAnHG,QAAQ;;;qBAuHN,QAAQ","file":"compiler.js","sourcesContent":["'use strict';\n\nimport jade from 'jade';\nimport File from 'fs';\nimport Path from 'path';\nimport _ from 'lodash';\nimport 'source-map-support/register';\n/**\n * The class that compiles the Jade template.\n * @class Compiler\n */\nclass Compiler {\n constructor(parser) {\n\n /**\n * Jade used to compile the documentation\n * @type {Jade} Jade compiler\n */\n this.jade = jade;\n\n // Set the options\n this.options = parser ? parser.options : {};\n // Sets the files from the parser\n this.files = parser ? parser.files : [];\n // Set up the compiler's code filter\n this.setCodeFilter();\n }\n /** \n * Compiles the docs\n * @param {Object} locals The local variable object\n * @param {String} template The template to compile\n * @jsFiddle https://jsfiddle.net/iwatakeshi/pmp9ygwL/embedded/\n * @return {String} The compiled content\n */\n compile(locals, template) {\n // Get the path (alias for filename)\n var {\n path\n } = this.options.template;\n // Return the compiled template\n return this.jade.compile(template || this.template, {\n pretty: true,\n filename: path\n })(locals);\n }\n /** \n * Compiles the docs with a specified path\n * @param {Object} path The path to compile\n * @param {Object} locals The local variable object\n * @param {String} template The template to compile\n * @return {String} The compiled content\n */\n compileWithPath(path, locals, template) {\n // Return the compiled template\n return this.jade.compile(template || this.template, {\n pretty: true,\n // Alias for filename\n filename: path\n })(locals);\n }\n /** \n * Sets the template\n * @param {String} template The template\n * @returns {Compiler} The compiler\n */\n setTemplate(template) {\n // Template used to produce the documentation\n this.template = template;\n return this;\n }\n\n /** \n * Sets the template\n * @param {String} path The path to the template\n * @returns {Compiler} The compiler\n */\n setTemplateWithPath(path) {\n // Template used to produce the documentation\n this.template = File.readFileSync(\n Path.resolve(__dirname, path ||\n this.options.template.path)).toString();\n return this;\n }\n\n /** \n * Sets custom filter(s)\n * @param {Array|Object} filters The custom filter(s) to set\n * @jsFiddle https://jsfiddle.net/iwatakeshi/sbr206cf/embedded/\n * @returns {Compiler} The compiler\n */\n setFilters(filters) {\n // Check if the fitlers is an object\n if (_.isPlainObject(filters)) {\n this.jade.filters[filters.name] = filters.filter;\n }\n // Check if the filters is an array\n if (_.isArray(filters)) {\n _.forEach(filters, (filter) => {\n this.jade.filters[filter.name] = filter.filter;\n });\n }\n return this;\n }\n\n /**\n * Sets the code filter for `:code`\n * @param {Function} filter The code filter to set\n * @returns {Compiler} The compiler\n */\n setCodeFilter(filter) {\n /**\n * Jade support for filter `:code`\n * @param {String} block\n * @return {String}\n */\n this.jade.filters.code = filter || function (block) {\n return block.replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/#/g, '#')\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/\\n/g, '\\\\n');\n };\n\n return this;\n }\n}\n\nexport\ndefault Compiler;"],"sourceRoot":"/source/"} -------------------------------------------------------------------------------- /src/compiler.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | Object.defineProperty(exports, '__esModule', { 4 | value: true 5 | }); 6 | 7 | var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); 8 | 9 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 10 | 11 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 12 | 13 | var _jade = require('jade'); 14 | 15 | var _jade2 = _interopRequireDefault(_jade); 16 | 17 | var _fs = require('fs'); 18 | 19 | var _fs2 = _interopRequireDefault(_fs); 20 | 21 | var _path = require('path'); 22 | 23 | var _path2 = _interopRequireDefault(_path); 24 | 25 | var _lodash = require('lodash'); 26 | 27 | var _lodash2 = _interopRequireDefault(_lodash); 28 | 29 | require('source-map-support/register'); 30 | 31 | /** 32 | * The class that compiles the Jade template. 33 | * @class Compiler 34 | */ 35 | 36 | var Compiler = (function () { 37 | function Compiler(parser) { 38 | _classCallCheck(this, Compiler); 39 | 40 | /** 41 | * Jade used to compile the documentation 42 | * @type {Jade} Jade compiler 43 | */ 44 | this.jade = _jade2['default']; 45 | 46 | // Set the options 47 | this.options = parser ? parser.options : {}; 48 | // Sets the files from the parser 49 | this.files = parser ? parser.files : []; 50 | // Set up the compiler's code filter 51 | this.setCodeFilter(); 52 | } 53 | 54 | /** 55 | * Compiles the docs 56 | * @param {Object} locals The local variable object 57 | * @param {String} template The template to compile 58 | * @jsFiddle https://jsfiddle.net/iwatakeshi/pmp9ygwL/embedded/ 59 | * @return {String} The compiled content 60 | */ 61 | 62 | _createClass(Compiler, [{ 63 | key: 'compile', 64 | value: function compile(locals, template) { 65 | // Get the path (alias for filename) 66 | var path = this.options.template.path; 67 | 68 | // Return the compiled template 69 | return this.jade.compile(template || this.template, { 70 | pretty: true, 71 | filename: path 72 | })(locals); 73 | } 74 | 75 | /** 76 | * Compiles the docs with a specified path 77 | * @param {Object} path The path to compile 78 | * @param {Object} locals The local variable object 79 | * @param {String} template The template to compile 80 | * @return {String} The compiled content 81 | */ 82 | }, { 83 | key: 'compileWithPath', 84 | value: function compileWithPath(path, locals, template) { 85 | // Return the compiled template 86 | return this.jade.compile(template || this.template, { 87 | pretty: true, 88 | // Alias for filename 89 | filename: path 90 | })(locals); 91 | } 92 | 93 | /** 94 | * Sets the template 95 | * @param {String} template The template 96 | * @returns {Compiler} The compiler 97 | */ 98 | }, { 99 | key: 'setTemplate', 100 | value: function setTemplate(template) { 101 | // Template used to produce the documentation 102 | this.template = template; 103 | return this; 104 | } 105 | 106 | /** 107 | * Sets the template 108 | * @param {String} path The path to the template 109 | * @returns {Compiler} The compiler 110 | */ 111 | }, { 112 | key: 'setTemplateWithPath', 113 | value: function setTemplateWithPath(path) { 114 | // Template used to produce the documentation 115 | this.template = _fs2['default'].readFileSync(_path2['default'].resolve(__dirname, path || this.options.template.path)).toString(); 116 | return this; 117 | } 118 | 119 | /** 120 | * Sets custom filter(s) 121 | * @param {Array|Object} filters The custom filter(s) to set 122 | * @jsFiddle https://jsfiddle.net/iwatakeshi/sbr206cf/embedded/ 123 | * @returns {Compiler} The compiler 124 | */ 125 | }, { 126 | key: 'setFilters', 127 | value: function setFilters(filters) { 128 | var _this = this; 129 | 130 | // Check if the fitlers is an object 131 | if (_lodash2['default'].isPlainObject(filters)) { 132 | this.jade.filters[filters.name] = filters.filter; 133 | } 134 | // Check if the filters is an array 135 | if (_lodash2['default'].isArray(filters)) { 136 | _lodash2['default'].forEach(filters, function (filter) { 137 | _this.jade.filters[filter.name] = filter.filter; 138 | }); 139 | } 140 | return this; 141 | } 142 | 143 | /** 144 | * Sets the code filter for `:code` 145 | * @param {Function} filter The code filter to set 146 | * @returns {Compiler} The compiler 147 | */ 148 | }, { 149 | key: 'setCodeFilter', 150 | value: function setCodeFilter(filter) { 151 | /** 152 | * Jade support for filter `:code` 153 | * @param {String} block 154 | * @return {String} 155 | */ 156 | this.jade.filters.code = filter || function (block) { 157 | return block.replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"').replace(/#/g, '#').replace(/\\/g, '\\\\').replace(/\n/g, '\\n'); 158 | }; 159 | 160 | return this; 161 | } 162 | }]); 163 | 164 | return Compiler; 165 | })(); 166 | 167 | exports['default'] = Compiler; 168 | module.exports = exports['default']; 169 | //# sourceMappingURL=source maps/compiler.js.map -------------------------------------------------------------------------------- /lib/mr-doc.js: -------------------------------------------------------------------------------- 1 | /*! global process */ 2 | 'use strict'; 3 | 4 | import File from 'fs'; 5 | import Path from 'path'; 6 | import _ from 'lodash'; 7 | import Compiler from './compiler'; 8 | import Parser from './parser'; 9 | import Markdown from 'markdown-it'; 10 | import mkdirp from 'mkdirp'; 11 | import Theme from './theme'; 12 | 13 | /** 14 | * The main class that creates beautiful documentations. 15 | * @class Doxx 16 | * @extend Compiler 17 | */ 18 | class Doxx extends Compiler { 19 | // Initialize the compiler 20 | // and pass the parser. 21 | constructor(options) { 22 | super(new Parser(options)); 23 | // Set the locals stack 24 | this.locals = []; 25 | } 26 | /** 27 | * Generates the documentations. 28 | */ 29 | generate() { 30 | // Compute all symboles 31 | var allSymbols = this.files.reduce(function (m, a) { 32 | m = m.concat(a.symbols || []); 33 | return m; 34 | }, []); 35 | 36 | var pkg; 37 | // Get package.json 38 | try { 39 | pkg = require(process.cwd() + '/package'); 40 | } catch (err) {} 41 | 42 | var readme = pkg && pkg.readme, 43 | readMeFile = Path.resolve(process.cwd(), this.options.readme || 44 | (pkg && pkg.readmeFileName) || 'README.md'); 45 | 46 | if (!readme && File.existsSync(readMeFile)) { 47 | readme = File.readFileSync(readMeFile).toString(); 48 | } else { 49 | console.warn( 50 | new Error('Doxx [warn]: No README.md file found at ' + readMeFile)); 51 | } 52 | 53 | if (!readme) { 54 | console.warn( 55 | new Error('Doxx [warn]: Empty README.md ' + readMeFile)); 56 | readme = ''; 57 | } 58 | 59 | var md = new Markdown(); 60 | md = md.render.bind(md); 61 | 62 | // Get readme data 63 | this.files.unshift({ 64 | name: 'Main', 65 | targetName: 'index.html', 66 | readme: md(readme), 67 | dox: [], 68 | symbols: [] 69 | }); 70 | 71 | // Set title 72 | var title = pkg && pkg.name ? pkg.name : 73 | this.options.title; 74 | 75 | // Set description 76 | var description = pkg && pkg.description ? 77 | pkg.description : ''; 78 | 79 | // Set URLs 80 | var url = { 81 | github: pkg && pkg.homepage ? 82 | pkg.homepage.indexOf('github') > -1 ? 83 | pkg.homepage : false : false, 84 | npm: pkg && pkg.name ? 85 | 'https://npmjs.com/package/' + pkg.name : false, 86 | homepage: pkg && pkg.homepage ? 87 | pkg.homepage.indexOf('github') === -1 ? 88 | pkg.homepage : false : false 89 | }; 90 | 91 | // Make sure the folder structure in target mirrors source 92 | var folders = []; 93 | 94 | this.files.forEach(file => { 95 | var folder = file.targetName 96 | .substr(0, file.targetName.lastIndexOf(Path.sep)); 97 | 98 | if ((folder !== '') && (folders.indexOf(folder) === -1)) { 99 | folders.push(folder); 100 | mkdirp.sync(this.options.target + '/' + folder); 101 | } 102 | }); 103 | 104 | // Set each files relName in relation 105 | // to where this file is in the directory tree 106 | this.files.forEach(file => { 107 | file.targets = this.getTargets(file); 108 | }); 109 | 110 | this.files.forEach((file) => { 111 | // Set locals 112 | this.locals.push(_.assign({}, file, { 113 | project: { 114 | title, description, url 115 | }, 116 | allSymbols: allSymbols, 117 | files: this.files, 118 | current: { 119 | name: file.name 120 | }, 121 | file: { 122 | targets: file.targets 123 | } 124 | })); 125 | }); 126 | 127 | // Install theme 128 | (new Theme(this.options)).install().then((result) => { 129 | var { 130 | isCached, theme 131 | } = result; 132 | 133 | if (theme) { 134 | console.info('Doxx [info]: Installed theme: ' + 135 | theme + (isCached ? ' from cache.' : '')); 136 | } 137 | _.forEach(this.files, (file, index) => { 138 | // Set template 139 | this.setTemplate(result.template); 140 | // Compile the template 141 | let compiled = this.compile(this.locals[index]); 142 | // Write files 143 | mkdirp(this.options.target, error => { 144 | if (error) return; 145 | else 146 | File.writeFileSync(Path.join( 147 | this.options.target, file.targetName), 148 | compiled); 149 | }); 150 | }); 151 | }, console.error); 152 | } 153 | /** 154 | * Return the targets for the specified file 155 | * @private 156 | * @param {Object} file The file to generate 157 | * @return {Object} The iterator 158 | */ 159 | getTargets(file) { 160 | return _.map(this.files, (f) => { 161 | 162 | // Count how deep the current file is in relation to base 163 | var count = file.name.split('/'); 164 | count = count === null ? 0 : count.length - 1; 165 | 166 | // relName is equal to targetName at the base dir 167 | f.relative = { 168 | name: f.targetName, 169 | path: '' 170 | }; 171 | // For each directory in depth of current file 172 | // add a ../ to the relative filename of this link 173 | while (count > 0) { 174 | f.relative.name = '../' + f.relative.name; 175 | f.relative.path += '../'; 176 | count--; 177 | } 178 | // Set the target for each folder 179 | // to support nested directories 180 | // and allow asset files to access the dir 181 | return { 182 | file: { 183 | name: f.name 184 | }, 185 | target: { 186 | name: f.targetName 187 | }, 188 | relative: f.relative 189 | }; 190 | }); 191 | } 192 | } 193 | export default function (options) { 194 | return new Doxx(options); 195 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mr-doc [](https://david-dm.org/mr-doc/mr-doc) [](https://david-dm.org/mr-doc/mr-doc) [](https://travis-ci.org/mr-doc/mr-doc) 2 | 3 | mr-doc is a total refactoring of [dox-foundation](https://github.com/punkave/dox-foundation/) written in ES6, tranformed to ES5 with [Babel](https://babeljs.io/), and is based on [dox](https://github.com/visionmedia/dox). It can automatically generate beautiful documentations and can further spice up your documentations using themes. 4 | 5 | By default, mr-doc uses [mr-doc-theme-default](https://www.github.com/mr-doc/mr-doc-theme-default) which uses 6 | [Twitter Bootstrap](https://twitter.github.com/bootstrap/) for the frontend framework and [Prism.js](http://prismjs.com/) 7 | for syntax highlighting. 8 | 9 | ## Docs 10 | 11 | The beautifully documentation can be found at [GitHub](http://fgribreau.github.io/doxx/docs/). 12 | 13 | 14 | ## Installation 15 | 16 | ```bash 17 | # Install the module globally 18 | $ npm i -g mr-doc 19 | ``` 20 | 21 | ## Usage 22 | 23 | JavaScript JavaDoc style 24 | 25 | ```javascript 26 | /** 27 | * Create an array of all the right files in the source dir 28 | * @param {String} source path 29 | * @param {Object} options 30 | * @param {Function} callback 31 | * @jsFiddle A jsFiddle embed URL 32 | * @return {Array} an array of string path 33 | */ 34 | function collectFiles(source, options, callback) { 35 | ... 36 | } 37 | 38 | ``` 39 | 40 | CoffeeScript JavaDoc style 41 | 42 | ```coffeescript 43 | ###* 44 | * Create an array of all the right files in the source dir 45 | * @param {String} source path 46 | * @param {Object} options 47 | * @param {Function} callback 48 | * @jsFiddle A jsFiddle embed URL 49 | * @return {Array} an array of string path 50 | ### 51 | collectFiles = (source, options, callback) -> 52 | ... 53 | 54 | ``` 55 | 56 | ***Notes*** 57 | 58 | * mr-doc supports the following variations of `@return` and `@jsFiddle`: 59 | * `@return`, `@returns` 60 | * `@jsfiddle`, `@jsFiddle`, `@JSFiddle` 61 | 62 | 63 | ## CLI 64 | ```bash 65 | $ mr-doc --help 66 | 67 | Usage: mr-doc [options] 68 | 69 | Commands: 70 | cache Manages the mr-doc cache. The available commands are clean and remove. 71 | 72 | Options: 73 | 74 | -h, --help Outputs usage information. 75 | -V, --version Outputs the version number. 76 | -r, --raw Outputs "raw" comments, leaving the markdown intact. 77 | -d, --debug Outputs parsed comments for debugging. 78 | -t, --title' + descriptions[0].string + '
'; 193 | } 194 | 195 | if (jsfiddles.length === 1) { 196 | symbol.jsfiddle = jsfiddles[0].string; 197 | } 198 | 199 | return symbol; 200 | } 201 | }]); 202 | 203 | return Symbol; 204 | })(); 205 | 206 | exports['default'] = Symbol; 207 | module.exports = exports['default']; 208 | //# sourceMappingURL=source maps/symbol.js.map -------------------------------------------------------------------------------- /src/theme.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | Object.defineProperty(exports, '__esModule', { 3 | value: true 4 | }); 5 | 6 | var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); 7 | 8 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 9 | 10 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 11 | 12 | var _when = require('when'); 13 | 14 | var _when2 = _interopRequireDefault(_when); 15 | 16 | var _path = require('path'); 17 | 18 | var _path2 = _interopRequireDefault(_path); 19 | 20 | var _lodash = require('lodash'); 21 | 22 | var _lodash2 = _interopRequireDefault(_lodash); 23 | 24 | var _fs = require('fs'); 25 | 26 | var _fs2 = _interopRequireDefault(_fs); 27 | 28 | var _fsExtra = require('fs-extra'); 29 | 30 | var _fsExtra2 = _interopRequireDefault(_fsExtra); 31 | 32 | var _elegantSpinner = require('elegant-spinner'); 33 | 34 | var _elegantSpinner2 = _interopRequireDefault(_elegantSpinner); 35 | 36 | var _logUpdate = require('log-update'); 37 | 38 | var _logUpdate2 = _interopRequireDefault(_logUpdate); 39 | 40 | require('source-map-support/register'); 41 | 42 | var frame = (0, _elegantSpinner2['default'])(); 43 | 44 | /** 45 | * The class that locates themes 46 | * @class Theme 47 | */ 48 | 49 | var Theme = (function () { 50 | function Theme(options) { 51 | _classCallCheck(this, Theme); 52 | 53 | var resolved = { 54 | theme: this.locateTheme(options.theme) 55 | }; 56 | 57 | this.options = { 58 | theme: { 59 | name: resolved.theme.name, 60 | path: resolved.theme.path 61 | }, 62 | target: { 63 | path: options.target 64 | } 65 | }; 66 | } 67 | 68 | /** 69 | * Find the theme specified 70 | */ 71 | 72 | _createClass(Theme, [{ 73 | key: 'locateTheme', 74 | value: function locateTheme(theme) { 75 | 76 | var DEFAULT_THEME = 'doxx-theme-default'; 77 | 78 | var doxxPath = _path2['default'].resolve(__dirname, '..'); 79 | var projectPath = process.cwd(); 80 | 81 | var locations = { 82 | project: _path2['default'].join(projectPath, 'node_modules', theme), 83 | doxx: _path2['default'].join(doxxPath, 'node_modules', theme), 84 | 'default': _path2['default'].join(doxxPath, 'node_modules', DEFAULT_THEME) 85 | }; 86 | 87 | var exists = _fs2['default'].existsSync(locations.doxx); 88 | if (exists) { 89 | console.log('Doxx [info]: Using theme [' + theme + ']'); 90 | return { 91 | name: theme, 92 | path: locations.doxx 93 | }; 94 | } 95 | 96 | exists = _fs2['default'].existsSync(locations.project); 97 | if (exists) { 98 | console.log('Doxx [info]: Using theme [' + theme + ']'); 99 | return { 100 | name: theme, 101 | path: locations.project 102 | }; 103 | } 104 | 105 | console.log('Doxx [warning]: theme "' + theme + '" not found, reverting to default.'); 106 | 107 | return { 108 | name: DEFAULT_THEME, 109 | path: locations['default'] 110 | }; 111 | } 112 | 113 | /** 114 | * Copies the theme specified (reverting to default) 115 | * over to the target directory. 116 | */ 117 | }, { 118 | key: 'install', 119 | 120 | /** 121 | * Copies the specific theme assets over to the target directory 122 | * and returns the 123 | */ 124 | value: function install() { 125 | return Theme.configure(this.options); 126 | } 127 | }], [{ 128 | key: 'configure', 129 | value: function configure(options) { 130 | 131 | var final = _when2['default'].defer(); 132 | 133 | // Sources 134 | var config = { 135 | src: options.theme.path, 136 | dest: options.target.path, 137 | paths: { 138 | css: { 139 | src: 'assets/css', 140 | dest: 'css' 141 | }, 142 | js: { 143 | src: 'assets/js', 144 | dest: 'js' 145 | } 146 | } 147 | }; 148 | 149 | /** 150 | * The commands to install the theme 151 | * @type {object} 152 | */ 153 | var commands = { 154 | showProgress: function showProgress(command) { 155 | var count = 0; 156 | while (count < 200) { 157 | (0, _logUpdate2['default'])('Doxx [info]: ' + frame() + ' ' + command); 158 | count++; 159 | } 160 | }, 161 | /** 162 | * Create necessary paths to destination folder 163 | */ 164 | copyAssets: function copyAssets() { 165 | var types = _lodash2['default'].keys(config.paths); 166 | var m = _when2['default'].map(types, function (type) { 167 | var d = _when2['default'].defer(); 168 | var src = _path2['default'].join(config.src, config.paths[type].src); 169 | var dest = _path2['default'].join(config.dest, config.paths[type].dest); 170 | _fsExtra2['default'].copy(src, dest, { 171 | clobber: true 172 | }, function (error) { 173 | if (error) d.reject(error);else { 174 | d.resolve(); 175 | } 176 | }); 177 | return d.promise; 178 | }); 179 | return m; 180 | }, 181 | /** 182 | * Reads the template from the source and strigifies it. 183 | */ 184 | stringifyTemplate: function stringifyTemplate() { 185 | var d = _when2['default'].defer(); 186 | var file = _path2['default'].join(config.src, 'template/index.jade'); 187 | _fsExtra2['default'].readFile(file, function (error, data) { 188 | if (error) d.reject(error);else d.resolve({ 189 | template: data.toString() 190 | }); 191 | }); 192 | return d.promise; 193 | } 194 | }; 195 | 196 | // Check if the template is enabled (legacy) 197 | if (options.template && options.template.path) { 198 | final.resolve({ 199 | template: _fsExtra2['default'].readFileSync(_path2['default'].resolve(__dirname, options.template.path)).toString() 200 | }); 201 | } else { 202 | (function () { 203 | return commands.copyAssets().then(commands.stringifyTemplate).then(final.resolve); 204 | })(commands.showProgress); 205 | } 206 | return final.promise; 207 | } 208 | }]); 209 | 210 | return Theme; 211 | })(); 212 | 213 | exports['default'] = Theme; 214 | module.exports = exports['default']; 215 | //# sourceMappingURL=source maps/theme.js.map -------------------------------------------------------------------------------- /src/source maps/theme.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["theme.js"],"names":[],"mappings":"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","file":"theme.js","sourcesContent":["'use strict';\nimport when from 'when';\nimport Path from 'path';\nimport _ from 'lodash';\nimport fs from 'fs';\nimport File from 'fs-extra';\nimport elegantSpinner from 'elegant-spinner';\nimport logUpdate from 'log-update';\nimport 'source-map-support/register';\n\nlet frame = elegantSpinner();\n\n/**\n * The class that locates themes\n * @class Theme\n */\nclass Theme {\n constructor(options) {\n\n let resolved = {\n theme: this.locateTheme(options.theme)\n };\n\n this.options = {\n theme: {\n name: resolved.theme.name,\n path: resolved.theme.path\n },\n target: {\n path: options.target\n }\n };\n\n }\n\n /**\n * Find the theme specified\n */\n locateTheme(theme) {\n\n const DEFAULT_THEME = 'doxx-theme-default';\n\n const doxxPath = Path.resolve(__dirname, '..');\n const projectPath = process.cwd();\n\n const locations = {\n project: Path.join(projectPath,\n 'node_modules',\n theme),\n doxx: Path.join(doxxPath,\n 'node_modules',\n theme),\n default: Path.join(doxxPath,\n 'node_modules',\n DEFAULT_THEME)\n };\n\n\n let exists = fs.existsSync(locations.doxx);\n if (exists) {\n console.log('Doxx [info]: Using theme [' + theme + ']');\n return {\n name: theme,\n path: locations.doxx\n };\n }\n\n exists = fs.existsSync(locations.project);\n if (exists) {\n console.log('Doxx [info]: Using theme [' + theme + ']');\n return {\n name: theme,\n path: locations.project\n };\n }\n\n console.log('Doxx [warning]: theme \"' +\n theme +\n '\" not found, reverting to default.');\n\n return {\n name: DEFAULT_THEME,\n path: locations.default\n };\n\n }\n\n /** \n * Copies the theme specified (reverting to default)\n * over to the target directory.\n */\n static configure(options) {\n\n let final = when.defer();\n\n // Sources\n let config = {\n src: options.theme.path,\n dest: options.target.path,\n paths: {\n css: {\n src: 'assets/css',\n dest: 'css'\n },\n js: {\n src: 'assets/js',\n dest: 'js'\n }\n }\n };\n\n /** \n * The commands to install the theme\n * @type {object}\n */\n let commands = {\n showProgress: (command) => {\n var count = 0;\n while (count < 200) {\n logUpdate('Doxx [info]: ' + frame() + ' ' + command);\n count++;\n }\n },\n /**\n * Create necessary paths to destination folder\n */\n copyAssets: () => {\n let types = _.keys(config.paths);\n let m = when.map(types, function (type) {\n let d = when.defer();\n let src = Path.join(config.src, config.paths[type].src);\n let dest = Path.join(config.dest, config.paths[type].dest);\n File.copy(src, dest, {\n clobber: true\n }, error => {\n if (error) d.reject(error);\n else {\n d.resolve();\n }\n });\n return d.promise;\n });\n return m;\n },\n /** \n * Reads the template from the source and strigifies it.\n */\n stringifyTemplate: () => {\n let d = when.defer();\n let file = Path.join(config.src, 'template/index.jade');\n File.readFile(file, (error, data) => {\n if (error) d.reject(error);\n else d.resolve({\n template: data.toString()\n });\n });\n return d.promise;\n }\n };\n\n // Check if the template is enabled (legacy)\n if (options.template && options.template.path) {\n final.resolve({\n template: File.readFileSync(\n Path.resolve(__dirname,\n options.template.path)).toString()\n });\n } else {\n (() => {\n return commands.copyAssets()\n .then(commands.stringifyTemplate)\n .then(final.resolve);\n })(commands.showProgress);\n }\n return final.promise;\n }\n /** \n * Copies the specific theme assets over to the target directory\n * and returns the \n */\n install() {\n return Theme.configure(this.options);\n }\n}\n\nexport default Theme;"],"sourceRoot":"/source/"} -------------------------------------------------------------------------------- /src/source maps/symbol.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["symbol.js"],"names":[],"mappings":"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","file":"symbol.js","sourcesContent":["'use strict';\n\nimport _ from 'lodash';\nimport 'source-map-support/register';\n\n/**\n * The class that manges symbols.\n * @class Symbol\n */\nclass Symbol {\n constructor() {}\n /**\n * Returns the structure of a parsed file\n * @param {Array} symbols array of symbols\n * @param {String} file filename\n * @return {Array}\n */\n static structure(symbols, file) {\n return _.compact(symbols.map(function (method) {\n if (!method.ctx || !method.ctx.name) {\n return null;\n }\n return {\n targetFile: file,\n name: method.ctx.name,\n type: method.ctx.type\n };\n })) || [];\n }\n /**\n * Checks if a tag has a specific type\n * @param {string} val value to check against\n * @return {function} A function that evaluates the truth\n * when True if `tag` type is `val`\n */\n static has(val) {\n return function (tag) {\n return tag.type === val;\n };\n }\n /**\n * Compacts multi-line expression\n * @return {Array}\n */\n static compact(tags) {\n\n // [{\"type\":\"description\",\n // \"string\":\"Note: if `addClass` is defined at the step level.\"},\n // {\"type\":\"\",\n // \"string\": \"The two defined `addClass` \n // will be taken into account in the popover\"},\n // {\"type\":\"type\",\"types\":[\"String\"]}]\n var compacted = [];\n\n tags.forEach(function (tag, i) {\n if (!tag.type) {\n if (i === 0) {\n return;\n }\n // Append to previous\n var prevTag = compacted[compacted.length - 1];\n if (prevTag.description) {\n prevTag.description += ' ' + tag.string;\n } else {\n prevTag.string += ' ' + tag.string;\n }\n return;\n }\n\n compacted.push(tag);\n });\n\n return compacted;\n }\n\n /**\n * Maps symbols\n * @private\n * @param {Object} symbol\n * @return {Object}\n */\n static map(symbol) {\n symbol.tags = Symbol.compact(symbol.tags);\n var tags = {};\n ['type', 'description', 'example', 'file', 'fileoverview',\n 'overview', 'param', 'require',\n 'jsfiddle', 'jsFiddle', 'JSFiddle',\n 'return', 'returns'\n ].forEach(tag => {\n // Handle special cases\n if (tag.match(/(return|returns)\\b/))\n tags.returns = symbol.tags.filter((s) => {\n return Symbol.has('return')(s) ||\n Symbol.has('returns')(s);\n });\n else if (tag.match(/(jsfiddle|jsFiddle|JSFiddle)\\b/)) {\n tags.jsfiddles = symbol.tags.filter((s) => {\n return Symbol.has('jsfiddle')(s) ||\n Symbol.has('jsFiddle')(s) ||\n Symbol.has('JSFiddle')(s);\n });\n } else tags[tag.toLowerCase() + 's'] =\n symbol.tags.filter(Symbol.has(tag));\n });\n var {\n types, descriptions, examples, files, fileoverviews,\n overviews, returns, requires, jsfiddles\n } = tags;\n if (symbol.tags.length > 0 &&\n symbol.tags.filter(Symbol.has('param')).length > 0) {\n\n symbol.hasParams = true;\n }\n\n if (!symbol.ctx) {\n symbol.ctx = {};\n }\n\n if (symbol.ctx.type) {\n symbol.gtype = symbol.ctx.type;\n }\n\n if (types.length === 1) {\n symbol.type = types[0].types.join(' | ');\n }\n\n if (files.length === 1) {\n symbol.file = files[0].type;\n symbol.fileString = files[0].string;\n symbol.fileHtml = files[0].html;\n }\n\n if (fileoverviews.length === 1) {\n symbol.files = fileoverviews[0].type;\n symbol.fileString = fileoverviews[0].string;\n symbol.fileHtml = fileoverviews[0].html;\n }\n\n if (overviews.length === 1) {\n symbol.files = overviews[0].type;\n symbol.fileString = overviews[0].string;\n symbol.fileHtml = overviews[0].html;\n }\n\n if (returns.length !== 0) {\n symbol.returns = [];\n returns.forEach(function (returned) {\n symbol.returns.push(returned);\n });\n }\n\n if (examples.length !== 0) {\n symbol.examples = [];\n examples.forEach(function (example) {\n symbol.examples.push(example.string);\n });\n }\n\n if (requires.length !== 0) {\n symbol.requires = [];\n requires.forEach(function (required) {\n symbol.requires.push(required.string);\n });\n }\n\n // No idea what this is for but it's there anyways.\n symbol.description.extra = '';\n if (descriptions.length === 1) {\n symbol.description.extra = '' + descriptions[0].string + '
';\n }\n\n if (jsfiddles.length === 1) {\n symbol.jsfiddle = jsfiddles[0].string;\n }\n\n return symbol;\n }\n}\n\nexport default Symbol;"],"sourceRoot":"/source/"} -------------------------------------------------------------------------------- /src/doxx.js: -------------------------------------------------------------------------------- 1 | /*! global process */ 2 | 'use strict'; 3 | 4 | Object.defineProperty(exports, '__esModule', { 5 | value: true 6 | }); 7 | 8 | var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); 9 | 10 | var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; 11 | 12 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } 13 | 14 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } 15 | 16 | function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } 17 | 18 | var _fs = require('fs'); 19 | 20 | var _fs2 = _interopRequireDefault(_fs); 21 | 22 | var _path = require('path'); 23 | 24 | var _path2 = _interopRequireDefault(_path); 25 | 26 | var _lodash = require('lodash'); 27 | 28 | var _lodash2 = _interopRequireDefault(_lodash); 29 | 30 | var _compiler = require('./compiler'); 31 | 32 | var _compiler2 = _interopRequireDefault(_compiler); 33 | 34 | var _parser = require('./parser'); 35 | 36 | var _parser2 = _interopRequireDefault(_parser); 37 | 38 | var _markdownIt = require('markdown-it'); 39 | 40 | var _markdownIt2 = _interopRequireDefault(_markdownIt); 41 | 42 | var _mkdirp = require('mkdirp'); 43 | 44 | var _mkdirp2 = _interopRequireDefault(_mkdirp); 45 | 46 | var _theme = require('./theme'); 47 | 48 | var _theme2 = _interopRequireDefault(_theme); 49 | 50 | /** 51 | * The main class that creates beautiful documentations. 52 | * @class Doxx 53 | * @extend Compiler 54 | */ 55 | 56 | var Doxx = (function (_Compiler) { 57 | _inherits(Doxx, _Compiler); 58 | 59 | // Initialize the compiler 60 | // and pass the parser. 61 | 62 | function Doxx(options) { 63 | _classCallCheck(this, Doxx); 64 | 65 | _get(Object.getPrototypeOf(Doxx.prototype), 'constructor', this).call(this, new _parser2['default'](options)); 66 | // Set the locals stack 67 | this.locals = []; 68 | } 69 | 70 | /** 71 | * Generates the documentations. 72 | */ 73 | 74 | _createClass(Doxx, [{ 75 | key: 'generate', 76 | value: function generate() { 77 | var _this = this; 78 | 79 | // Compute all symboles 80 | var allSymbols = this.files.reduce(function (m, a) { 81 | m = m.concat(a.symbols || []); 82 | return m; 83 | }, []); 84 | 85 | var pkg; 86 | // Get package.json 87 | try { 88 | pkg = require(process.cwd() + '/package'); 89 | } catch (err) {} 90 | 91 | var readme = pkg && pkg.readme, 92 | readMeFile = _path2['default'].resolve(process.cwd(), this.options.readme || pkg && pkg.readmeFileName || 'README.md'); 93 | 94 | if (!readme && _fs2['default'].existsSync(readMeFile)) { 95 | readme = _fs2['default'].readFileSync(readMeFile).toString(); 96 | } else { 97 | console.warn(new Error('Doxx [warn]: No README.md file found at ' + readMeFile)); 98 | } 99 | 100 | if (!readme) { 101 | console.warn(new Error('Doxx [warn]: Empty README.md ' + readMeFile)); 102 | readme = ''; 103 | } 104 | 105 | var md = new _markdownIt2['default'](); 106 | md = md.render.bind(md); 107 | 108 | // Get readme data 109 | this.files.unshift({ 110 | name: 'Main', 111 | targetName: 'index.html', 112 | readme: md(readme), 113 | dox: [], 114 | symbols: [] 115 | }); 116 | 117 | // Set title 118 | var title = pkg && pkg.name ? pkg.name : this.options.title; 119 | 120 | // Set description 121 | var description = pkg && pkg.description ? pkg.description : ''; 122 | 123 | // Set URLs 124 | var url = { 125 | github: pkg && pkg.homepage ? pkg.homepage.indexOf('github') > -1 ? pkg.homepage : false : false, 126 | npm: pkg && pkg.name ? 'https://npmjs.com/package/' + pkg.name : false, 127 | homepage: pkg && pkg.homepage ? pkg.homepage.indexOf('github') === -1 ? pkg.homepage : false : false 128 | }; 129 | 130 | // Make sure the folder structure in target mirrors source 131 | var folders = []; 132 | 133 | this.files.forEach(function (file) { 134 | var folder = file.targetName.substr(0, file.targetName.lastIndexOf(_path2['default'].sep)); 135 | 136 | if (folder !== '' && folders.indexOf(folder) === -1) { 137 | folders.push(folder); 138 | _mkdirp2['default'].sync(_this.options.target + '/' + folder); 139 | } 140 | }); 141 | 142 | // Set each files relName in relation 143 | // to where this file is in the directory tree 144 | this.files.forEach(function (file) { 145 | file.targets = _this.getTargets(file); 146 | }); 147 | 148 | this.files.forEach(function (file) { 149 | // Set locals 150 | _this.locals.push(_lodash2['default'].assign({}, file, { 151 | project: { 152 | title: title, description: description, url: url 153 | }, 154 | allSymbols: allSymbols, 155 | files: _this.files, 156 | current: { 157 | name: file.name 158 | }, 159 | file: { 160 | targets: file.targets 161 | } 162 | })); 163 | }); 164 | 165 | // Install theme 166 | new _theme2['default'](this.options).install().then(function (result) { 167 | var isCached = result.isCached; 168 | var theme = result.theme; 169 | 170 | if (theme) { 171 | console.info('Doxx [info]: Installed theme: ' + theme + (isCached ? ' from cache.' : '')); 172 | } 173 | _lodash2['default'].forEach(_this.files, function (file, index) { 174 | // Set template 175 | _this.setTemplate(result.template); 176 | // Compile the template 177 | var compiled = _this.compile(_this.locals[index]); 178 | // Write files 179 | (0, _mkdirp2['default'])(_this.options.target, function (error) { 180 | if (error) return;else _fs2['default'].writeFileSync(_path2['default'].join(_this.options.target, file.targetName), compiled); 181 | }); 182 | }); 183 | }, console.error); 184 | } 185 | 186 | /** 187 | * Return the targets for the specified file 188 | * @private 189 | * @param {Object} file The file to generate 190 | * @return {Object} The iterator 191 | */ 192 | }, { 193 | key: 'getTargets', 194 | value: function getTargets(file) { 195 | return _lodash2['default'].map(this.files, function (f) { 196 | 197 | // Count how deep the current file is in relation to base 198 | var count = file.name.split('/'); 199 | count = count === null ? 0 : count.length - 1; 200 | 201 | // relName is equal to targetName at the base dir 202 | f.relative = { 203 | name: f.targetName, 204 | path: '' 205 | }; 206 | // For each directory in depth of current file 207 | // add a ../ to the relative filename of this link 208 | while (count > 0) { 209 | f.relative.name = '../' + f.relative.name; 210 | f.relative.path += '../'; 211 | count--; 212 | } 213 | // Set the target for each folder 214 | // to support nested directories 215 | // and allow asset files to access the dir 216 | return { 217 | file: { 218 | name: f.name 219 | }, 220 | target: { 221 | name: f.targetName 222 | }, 223 | relative: f.relative 224 | }; 225 | }); 226 | } 227 | }]); 228 | 229 | return Doxx; 230 | })(_compiler2['default']); 231 | 232 | exports['default'] = function (options) { 233 | return new Doxx(options); 234 | }; 235 | 236 | module.exports = exports['default']; 237 | //# sourceMappingURL=source maps/doxx.js.map -------------------------------------------------------------------------------- /src/source maps/doxx.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["doxx.js"],"names":[],"mappings":";AACA,YAAY,CAAC;;;;;;;;;;;;;;;;kBAEI,IAAI;;;;oBACJ,MAAM;;;;sBACT,QAAQ;;;;wBACD,YAAY;;;;sBACd,UAAU;;;;0BACR,aAAa;;;;sBACf,QAAQ;;;;qBACT,SAAS;;;;;;;;;;IAOrB,IAAI;YAAJ,IAAI;;;;;AAGG,WAHP,IAAI,CAGI,OAAO,EAAE;0BAHjB,IAAI;;AAIJ,+BAJA,IAAI,6CAIE,wBAAW,OAAO,CAAC,EAAE;;AAE3B,QAAI,CAAC,MAAM,GAAG,EAAE,CAAC;GAClB;;;;;;eAPC,IAAI;;WAWA,oBAAG;;;;AAEP,UAAI,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE;AACjD,SAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;AAC9B,eAAO,CAAC,CAAC;OACV,EAAE,EAAE,CAAC,CAAC;;AAEP,UAAI,GAAG,CAAC;;AAER,UAAI;AACF,WAAG,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC,CAAC;OAC3C,CAAC,OAAO,GAAG,EAAE,EAAE;;AAEhB,UAAI,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM;UAC5B,UAAU,GAAG,kBAAK,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM,IACzD,GAAG,IAAI,GAAG,CAAC,cAAc,AAAC,IAAI,WAAW,CAAC,CAAC;;AAEhD,UAAI,CAAC,MAAM,IAAI,gBAAK,UAAU,CAAC,UAAU,CAAC,EAAE;AAC1C,cAAM,GAAG,gBAAK,YAAY,CAAC,UAAU,CAAC,CAAC,QAAQ,EAAE,CAAC;OACnD,MAAM;AACL,eAAO,CAAC,IAAI,CACV,IAAI,KAAK,CAAC,0CAA0C,GAAG,UAAU,CAAC,CAAC,CAAC;OACvE;;AAED,UAAI,CAAC,MAAM,EAAE;AACX,eAAO,CAAC,IAAI,CACV,IAAI,KAAK,CAAC,+BAA+B,GAAG,UAAU,CAAC,CAAC,CAAC;AAC3D,cAAM,GAAG,EAAE,CAAC;OACb;;AAED,UAAI,EAAE,GAAG,6BAAc,CAAC;AACxB,QAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;;;AAGxB,UAAI,CAAC,KAAK,CAAC,OAAO,CAAC;AACjB,YAAI,EAAE,MAAM;AACZ,kBAAU,EAAE,YAAY;AACxB,cAAM,EAAE,EAAE,CAAC,MAAM,CAAC;AAClB,WAAG,EAAE,EAAE;AACP,eAAO,EAAE,EAAE;OACZ,CAAC,CAAC;;;AAGH,UAAI,KAAK,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,GACpC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;;;AAGrB,UAAI,WAAW,GAAG,GAAG,IAAI,GAAG,CAAC,WAAW,GACtC,GAAG,CAAC,WAAW,GAAG,EAAE,CAAC;;;AAGvB,UAAI,GAAG,GAAG;AACR,cAAM,EAAE,GAAG,IAAI,GAAG,CAAC,QAAQ,GACzB,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,GACnC,GAAG,CAAC,QAAQ,GAAG,KAAK,GAAG,KAAK;AAC9B,WAAG,EAAE,GAAG,IAAI,GAAG,CAAC,IAAI,GAClB,4BAA4B,GAAG,GAAG,CAAC,IAAI,GAAG,KAAK;AACjD,gBAAQ,EAAE,GAAG,IAAI,GAAG,CAAC,QAAQ,GAC3B,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,GACrC,GAAG,CAAC,QAAQ,GAAG,KAAK,GAAG,KAAK;OAC/B,CAAC;;;AAGF,UAAI,OAAO,GAAG,EAAE,CAAC;;AAEjB,UAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAA,IAAI,EAAI;AACzB,YAAI,MAAM,GAAG,IAAI,CAAC,UAAU,CACzB,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,kBAAK,GAAG,CAAC,CAAC,CAAC;;AAEpD,YAAI,AAAC,MAAM,KAAK,EAAE,IAAM,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,AAAC,EAAE;AACvD,iBAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AACrB,8BAAO,IAAI,CAAC,MAAK,OAAO,CAAC,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC,CAAC;SACjD;OACF,CAAC,CAAC;;;;AAIH,UAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAA,IAAI,EAAI;AACzB,YAAI,CAAC,OAAO,GAAG,MAAK,UAAU,CAAC,IAAI,CAAC,CAAC;OACtC,CAAC,CAAC;;AAEH,UAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAC,IAAI,EAAK;;AAE3B,cAAK,MAAM,CAAC,IAAI,CAAC,oBAAE,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE;AAClC,iBAAO,EAAE;AACP,iBAAK,EAAL,KAAK,EAAE,WAAW,EAAX,WAAW,EAAE,GAAG,EAAH,GAAG;WACxB;AACD,oBAAU,EAAE,UAAU;AACtB,eAAK,EAAE,MAAK,KAAK;AACjB,iBAAO,EAAE;AACP,gBAAI,EAAE,IAAI,CAAC,IAAI;WAChB;AACD,cAAI,EAAE;AACJ,mBAAO,EAAE,IAAI,CAAC,OAAO;WACtB;SACF,CAAC,CAAC,CAAC;OACL,CAAC,CAAC;;;AAGH,AAAC,6BAAU,IAAI,CAAC,OAAO,CAAC,CAAE,OAAO,EAAE,CAAC,IAAI,CAAC,UAAC,MAAM,EAAK;YAEjD,QAAQ,GACN,MAAM,CADR,QAAQ;YAAE,KAAK,GACb,MAAM,CADE,KAAK;;AAGjB,YAAI,KAAK,EAAE;AACT,iBAAO,CAAC,IAAI,CAAC,gCAAgC,GAC3C,KAAK,IAAI,QAAQ,GAAG,cAAc,GAAG,EAAE,CAAA,AAAC,CAAC,CAAC;SAC7C;AACD,4BAAE,OAAO,CAAC,MAAK,KAAK,EAAE,UAAC,IAAI,EAAE,KAAK,EAAK;;AAErC,gBAAK,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;;AAElC,cAAI,QAAQ,GAAG,MAAK,OAAO,CAAC,MAAK,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;;AAEhD,mCAAO,MAAK,OAAO,CAAC,MAAM,EAAE,UAAA,KAAK,EAAI;AACnC,gBAAI,KAAK,EAAE,OAAO,KAEhB,gBAAK,aAAa,CAAC,kBAAK,IAAI,CACxB,MAAK,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,EACvC,QAAQ,CAAC,CAAC;WACf,CAAC,CAAC;SACJ,CAAC,CAAC;OACJ,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;KACnB;;;;;;;;;;WAOO,oBAAC,IAAI,EAAE;AACf,aAAO,oBAAE,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,UAAC,CAAC,EAAK;;;AAG9B,YAAI,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AACjC,aAAK,GAAG,KAAK,KAAK,IAAI,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;;;AAG9C,SAAC,CAAC,QAAQ,GAAG;AACX,cAAI,EAAE,CAAC,CAAC,UAAU;AAClB,cAAI,EAAE,EAAE;SACT,CAAC;;;AAGF,eAAO,KAAK,GAAG,CAAC,EAAE;AAChB,WAAC,CAAC,QAAQ,CAAC,IAAI,GAAG,KAAK,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;AAC1C,WAAC,CAAC,QAAQ,CAAC,IAAI,IAAI,KAAK,CAAC;AACzB,eAAK,EAAE,CAAC;SACT;;;;AAID,eAAO;AACL,cAAI,EAAE;AACJ,gBAAI,EAAE,CAAC,CAAC,IAAI;WACb;AACD,gBAAM,EAAE;AACN,gBAAI,EAAE,CAAC,CAAC,UAAU;WACnB;AACD,kBAAQ,EAAE,CAAC,CAAC,QAAQ;SACrB,CAAC;OACH,CAAC,CAAC;KACJ;;;SA7KG,IAAI;;;qBA+KK,UAAU,OAAO,EAAE;AAChC,SAAO,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;CAC1B","file":"doxx.js","sourcesContent":["/*! global process */\n'use strict';\n\nimport File from 'fs';\nimport Path from 'path';\nimport _ from 'lodash';\nimport Compiler from './compiler';\nimport Parser from './parser';\nimport Markdown from 'markdown-it';\nimport mkdirp from 'mkdirp';\nimport Theme from './theme';\n\n/**\n * The main class that creates beautiful documentations.\n * @class Doxx\n * @extend Compiler\n */\nclass Doxx extends Compiler {\n // Initialize the compiler\n // and pass the parser.\n constructor(options) {\n super(new Parser(options));\n // Set the locals stack\n this.locals = [];\n }\n /**\n * Generates the documentations.\n */\n generate() {\n // Compute all symboles\n var allSymbols = this.files.reduce(function (m, a) {\n m = m.concat(a.symbols || []);\n return m;\n }, []);\n\n var pkg;\n // Get package.json\n try {\n pkg = require(process.cwd() + '/package');\n } catch (err) {}\n\n var readme = pkg && pkg.readme,\n readMeFile = Path.resolve(process.cwd(), this.options.readme ||\n (pkg && pkg.readmeFileName) || 'README.md');\n\n if (!readme && File.existsSync(readMeFile)) {\n readme = File.readFileSync(readMeFile).toString();\n } else {\n console.warn(\n new Error('Doxx [warn]: No README.md file found at ' + readMeFile));\n }\n\n if (!readme) {\n console.warn(\n new Error('Doxx [warn]: Empty README.md ' + readMeFile));\n readme = '';\n }\n\n var md = new Markdown();\n md = md.render.bind(md);\n\n // Get readme data\n this.files.unshift({\n name: 'Main',\n targetName: 'index.html',\n readme: md(readme),\n dox: [],\n symbols: []\n });\n\n // Set title\n var title = pkg && pkg.name ? pkg.name :\n this.options.title;\n\n // Set description\n var description = pkg && pkg.description ?\n pkg.description : '';\n\n // Set URLs\n var url = {\n github: pkg && pkg.homepage ?\n pkg.homepage.indexOf('github') > -1 ?\n pkg.homepage : false : false,\n npm: pkg && pkg.name ?\n 'https://npmjs.com/package/' + pkg.name : false,\n homepage: pkg && pkg.homepage ?\n pkg.homepage.indexOf('github') === -1 ?\n pkg.homepage : false : false\n };\n\n // Make sure the folder structure in target mirrors source\n var folders = [];\n\n this.files.forEach(file => {\n var folder = file.targetName\n .substr(0, file.targetName.lastIndexOf(Path.sep));\n\n if ((folder !== '') && (folders.indexOf(folder) === -1)) {\n folders.push(folder);\n mkdirp.sync(this.options.target + '/' + folder);\n }\n });\n\n // Set each files relName in relation \n // to where this file is in the directory tree\n this.files.forEach(file => {\n file.targets = this.getTargets(file);\n });\n\n this.files.forEach((file) => {\n // Set locals\n this.locals.push(_.assign({}, file, {\n project: {\n title, description, url\n },\n allSymbols: allSymbols,\n files: this.files,\n current: {\n name: file.name\n },\n file: {\n targets: file.targets\n }\n }));\n });\n\n // Install theme\n (new Theme(this.options)).install().then((result) => {\n var {\n isCached, theme\n } = result;\n\n if (theme) {\n console.info('Doxx [info]: Installed theme: ' +\n theme + (isCached ? ' from cache.' : ''));\n }\n _.forEach(this.files, (file, index) => {\n // Set template\n this.setTemplate(result.template);\n // Compile the template\n let compiled = this.compile(this.locals[index]);\n // Write files\n mkdirp(this.options.target, error => {\n if (error) return;\n else\n File.writeFileSync(Path.join(\n this.options.target, file.targetName),\n compiled);\n });\n });\n }, console.error);\n }\n /** \n * Return the targets for the specified file\n * @private\n * @param {Object} file The file to generate\n * @return {Object} The iterator\n */\n getTargets(file) {\n return _.map(this.files, (f) => {\n\n // Count how deep the current file is in relation to base\n var count = file.name.split('/');\n count = count === null ? 0 : count.length - 1;\n\n // relName is equal to targetName at the base dir\n f.relative = {\n name: f.targetName,\n path: ''\n };\n // For each directory in depth of current file \n // add a ../ to the relative filename of this link\n while (count > 0) {\n f.relative.name = '../' + f.relative.name;\n f.relative.path += '../';\n count--;\n }\n // Set the target for each folder \n // to support nested directories\n // and allow asset files to access the dir\n return {\n file: {\n name: f.name\n },\n target: {\n name: f.targetName\n },\n relative: f.relative\n };\n });\n }\n}\nexport default function (options) {\n return new Doxx(options);\n}"],"sourceRoot":"/source/"} -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## [Unreleased](https://github.com/mr-doc/mr-doc/tree/HEAD) 4 | 5 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v2.1.1...HEAD) 6 | 7 | **Merged pull requests:** 8 | 9 | - Move docs out to docs task that pushes to gh-pages branch - wip [\#87](https://github.com/mr-doc/mr-doc/pull/87) ([cliftonc](https://github.com/cliftonc)) 10 | 11 | - Move of theme to npm modules [\#85](https://github.com/mr-doc/mr-doc/pull/85) ([cliftonc](https://github.com/cliftonc)) 12 | 13 | ## [v2.1.1](https://github.com/mr-doc/mr-doc/tree/v2.1.1) (2015-09-16) 14 | 15 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v2.1.0...v2.1.1) 16 | 17 | **Merged pull requests:** 18 | 19 | - 2.1.1 [\#84](https://github.com/mr-doc/mr-doc/pull/84) ([iwatakeshi](https://github.com/iwatakeshi)) 20 | 21 | - Fix GitHub Pages [\#82](https://github.com/mr-doc/mr-doc/pull/82) ([iwatakeshi](https://github.com/iwatakeshi)) 22 | 23 | - Fix Github Pages [\#81](https://github.com/mr-doc/mr-doc/pull/81) ([iwatakeshi](https://github.com/iwatakeshi)) 24 | 25 | ## [v2.1.0](https://github.com/mr-doc/mr-doc/tree/v2.1.0) (2015-09-14) 26 | 27 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v2.0.0...v2.1.0) 28 | 29 | **Implemented enhancements:** 30 | 31 | - Use update-notifier [\#78](https://github.com/mr-doc/mr-doc/issues/78) 32 | 33 | - Generate critical path from CSS [\#43](https://github.com/mr-doc/mr-doc/issues/43) 34 | 35 | - Minify CSS and JS [\#42](https://github.com/mr-doc/mr-doc/issues/42) 36 | 37 | - broken when viewed from https server [\#5](https://github.com/mr-doc/mr-doc/issues/5) 38 | 39 | **Merged pull requests:** 40 | 41 | - Update [\#77](https://github.com/mr-doc/mr-doc/pull/77) ([iwatakeshi](https://github.com/iwatakeshi)) 42 | 43 | - Update [\#76](https://github.com/mr-doc/mr-doc/pull/76) ([iwatakeshi](https://github.com/iwatakeshi)) 44 | 45 | - Update [\#75](https://github.com/mr-doc/mr-doc/pull/75) ([iwatakeshi](https://github.com/iwatakeshi)) 46 | 47 | - Patch [\#74](https://github.com/mr-doc/mr-doc/pull/74) ([iwatakeshi](https://github.com/iwatakeshi)) 48 | 49 | - Update Doxx [\#72](https://github.com/mr-doc/mr-doc/pull/72) ([iwatakeshi](https://github.com/iwatakeshi)) 50 | 51 | - 2.1.0 [\#80](https://github.com/mr-doc/mr-doc/pull/80) ([iwatakeshi](https://github.com/iwatakeshi)) 52 | 53 | ## [v2.0.0](https://github.com/mr-doc/mr-doc/tree/v2.0.0) (2015-09-03) 54 | 55 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v1.5.0...v2.0.0) 56 | 57 | **Closed issues:** 58 | 59 | - Using @description tag doubles the description [\#70](https://github.com/mr-doc/mr-doc/issues/70) 60 | 61 | - TypeLexerSyntaxError [\#69](https://github.com/mr-doc/mr-doc/issues/69) 62 | 63 | - Get exception when running doxx --source lib --target docs [\#64](https://github.com/mr-doc/mr-doc/issues/64) 64 | 65 | **Merged pull requests:** 66 | 67 | - Update Doxx [\#71](https://github.com/mr-doc/mr-doc/pull/71) ([iwatakeshi](https://github.com/iwatakeshi)) 68 | 69 | ## [v1.5.0](https://github.com/mr-doc/mr-doc/tree/v1.5.0) (2015-07-21) 70 | 71 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v1.4.0...v1.5.0) 72 | 73 | **Merged pull requests:** 74 | 75 | - add a space after commas for multiple values [\#68](https://github.com/mr-doc/mr-doc/pull/68) ([ForestMist](https://github.com/ForestMist)) 76 | 77 | ## [v1.4.0](https://github.com/mr-doc/mr-doc/tree/v1.4.0) (2015-05-30) 78 | 79 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v1.3.0...v1.4.0) 80 | 81 | **Merged pull requests:** 82 | 83 | - examples and returns [\#67](https://github.com/mr-doc/mr-doc/pull/67) ([scottnath](https://github.com/scottnath)) 84 | 85 | ## [v1.3.0](https://github.com/mr-doc/mr-doc/tree/v1.3.0) (2015-05-26) 86 | 87 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v1.2.8...v1.3.0) 88 | 89 | ## [v1.2.8](https://github.com/mr-doc/mr-doc/tree/v1.2.8) (2015-05-26) 90 | 91 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v1.2.7...v1.2.8) 92 | 93 | ## [v1.2.7](https://github.com/mr-doc/mr-doc/tree/v1.2.7) (2015-05-26) 94 | 95 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v1.2.6...v1.2.7) 96 | 97 | **Closed issues:** 98 | 99 | - Official template - return issue [\#65](https://github.com/mr-doc/mr-doc/issues/65) 100 | 101 | - praise: this is awesome [\#62](https://github.com/mr-doc/mr-doc/issues/62) 102 | 103 | **Merged pull requests:** 104 | 105 | - add return description to symbol object [\#66](https://github.com/mr-doc/mr-doc/pull/66) ([scottnath](https://github.com/scottnath)) 106 | 107 | ## [v1.2.6](https://github.com/mr-doc/mr-doc/tree/v1.2.6) (2015-03-18) 108 | 109 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v1.2.5...v1.2.6) 110 | 111 | **Closed issues:** 112 | 113 | - Information in the @return [\#56](https://github.com/mr-doc/mr-doc/issues/56) 114 | 115 | - TypeError 'undefined' when @return is empty [\#54](https://github.com/mr-doc/mr-doc/issues/54) 116 | 117 | **Merged pull requests:** 118 | 119 | - Fixes issue \#61 [\#63](https://github.com/mr-doc/mr-doc/pull/63) ([evertton](https://github.com/evertton)) 120 | 121 | ## [v1.2.5](https://github.com/mr-doc/mr-doc/tree/v1.2.5) (2015-01-31) 122 | 123 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v1.2.4...v1.2.5) 124 | 125 | **Closed issues:** 126 | 127 | - Weird return statement display + markup showing in the output. [\#58](https://github.com/mr-doc/mr-doc/issues/58) 128 | 129 | **Merged pull requests:** 130 | 131 | - Add jade != to stop html escape [\#59](https://github.com/mr-doc/mr-doc/pull/59) ([forstermatth](https://github.com/forstermatth)) 132 | 133 | - Add condition for return tag [\#60](https://github.com/mr-doc/mr-doc/pull/60) ([forstermatth](https://github.com/forstermatth)) 134 | 135 | ## [v1.2.4](https://github.com/mr-doc/mr-doc/tree/v1.2.4) (2015-01-22) 136 | 137 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v1.3.4...v1.2.4) 138 | 139 | ## [v1.3.4](https://github.com/mr-doc/mr-doc/tree/v1.3.4) (2015-01-22) 140 | 141 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v1.2.3...v1.3.4) 142 | 143 | ## [v1.2.3](https://github.com/mr-doc/mr-doc/tree/v1.2.3) (2015-01-22) 144 | 145 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v1.2.2...v1.2.3) 146 | 147 | ## [v1.2.2](https://github.com/mr-doc/mr-doc/tree/v1.2.2) (2015-01-22) 148 | 149 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v1.2.1...v1.2.2) 150 | 151 | **Closed issues:** 152 | 153 | - TypeError thrown in target option not specified [\#52](https://github.com/mr-doc/mr-doc/issues/52) 154 | 155 | **Merged pull requests:** 156 | 157 | - Updated dox version. Still works. [\#57](https://github.com/mr-doc/mr-doc/pull/57) ([trusktr](https://github.com/trusktr)) 158 | 159 | ## [v1.2.1](https://github.com/mr-doc/mr-doc/tree/v1.2.1) (2014-11-21) 160 | 161 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v1.2.0...v1.2.1) 162 | 163 | **Merged pull requests:** 164 | 165 | - \#52 Fixes TypeError thrown if target option not passed. [\#53](https://github.com/mr-doc/mr-doc/pull/53) ([gwagroves](https://github.com/gwagroves)) 166 | 167 | ## [v1.2.0](https://github.com/mr-doc/mr-doc/tree/v1.2.0) (2014-11-19) 168 | 169 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v1.1.1...v1.2.0) 170 | 171 | **Merged pull requests:** 172 | 173 | - Adding the ability to send in pre-compiled dox source [\#51](https://github.com/mr-doc/mr-doc/pull/51) ([leejt489](https://github.com/leejt489)) 174 | 175 | ## [v1.1.1](https://github.com/mr-doc/mr-doc/tree/v1.1.1) (2014-11-05) 176 | 177 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v1.1.0...v1.1.1) 178 | 179 | **Implemented enhancements:** 180 | 181 | - Expose `doxx` as a Node module [\#37](https://github.com/mr-doc/mr-doc/issues/37) 182 | 183 | **Closed issues:** 184 | 185 | - Error message when npm installing [\#48](https://github.com/mr-doc/mr-doc/issues/48) 186 | 187 | **Merged pull requests:** 188 | 189 | - Remove error message [\#49](https://github.com/mr-doc/mr-doc/pull/49) ([nicolasbrugneaux](https://github.com/nicolasbrugneaux)) 190 | 191 | ## [v1.1.0](https://github.com/mr-doc/mr-doc/tree/v1.1.0) (2014-11-05) 192 | 193 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v1.0.0...v1.1.0) 194 | 195 | **Closed issues:** 196 | 197 | - Ability to rename module name [\#46](https://github.com/mr-doc/mr-doc/issues/46) 198 | 199 | - Ability to ignore code blocks [\#45](https://github.com/mr-doc/mr-doc/issues/45) 200 | 201 | - CSS doesn't load on first load [\#44](https://github.com/mr-doc/mr-doc/issues/44) 202 | 203 | - Nav flickers when browser height is too short [\#41](https://github.com/mr-doc/mr-doc/issues/41) 204 | 205 | - Whitespace is missing between credits links [\#40](https://github.com/mr-doc/mr-doc/issues/40) 206 | 207 | - Displaying @return/@returns [\#35](https://github.com/mr-doc/mr-doc/issues/35) 208 | 209 | - Menu paths are incorrect on Windows [\#33](https://github.com/mr-doc/mr-doc/issues/33) 210 | 211 | - Doxx don't work with symbolic links [\#32](https://github.com/mr-doc/mr-doc/issues/32) 212 | 213 | - Functions within objects are not handled properly [\#26](https://github.com/mr-doc/mr-doc/issues/26) 214 | 215 | **Merged pull requests:** 216 | 217 | - Exposing as a node module [\#47](https://github.com/mr-doc/mr-doc/pull/47) ([leejt489](https://github.com/leejt489)) 218 | 219 | - Fixed incorrect file separator [\#34](https://github.com/mr-doc/mr-doc/pull/34) ([RogerNoble](https://github.com/RogerNoble)) 220 | 221 | - Updating marked dependency [\#36](https://github.com/mr-doc/mr-doc/pull/36) ([pdehaan](https://github.com/pdehaan)) 222 | 223 | ## [v1.0.0](https://github.com/mr-doc/mr-doc/tree/v1.0.0) (2014-10-16) 224 | 225 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v0.6.0...v1.0.0) 226 | 227 | **Fixed bugs:** 228 | 229 | - Dollar symbol breaking the UI [\#15](https://github.com/mr-doc/mr-doc/issues/15) 230 | 231 | **Closed issues:** 232 | 233 | - gittip image in README is 404ing [\#39](https://github.com/mr-doc/mr-doc/issues/39) 234 | 235 | - Doxx grunt task [\#31](https://github.com/mr-doc/mr-doc/issues/31) 236 | 237 | - Functions within objects are not handled properly [\#27](https://github.com/mr-doc/mr-doc/issues/27) 238 | 239 | - Doesn't work out-of-the-box [\#24](https://github.com/mr-doc/mr-doc/issues/24) 240 | 241 | - Inline comments break the output HTML [\#23](https://github.com/mr-doc/mr-doc/issues/23) 242 | 243 | - generating docs on Windows \(MSYSGIT\) does not work [\#6](https://github.com/mr-doc/mr-doc/issues/6) 244 | 245 | **Merged pull requests:** 246 | 247 | - Fixes style distruptancies for sidenav on long paths and lists [\#30](https://github.com/mr-doc/mr-doc/pull/30) ([wojciak](https://github.com/wojciak)) 248 | 249 | - Dangling text for symbol.name caused jade 1.1.5 to create a html element... [\#29](https://github.com/mr-doc/mr-doc/pull/29) ([wojciak](https://github.com/wojciak)) 250 | 251 | - Upgrade to latest version of Jade. [\#28](https://github.com/mr-doc/mr-doc/pull/28) ([hiddentao](https://github.com/hiddentao)) 252 | 253 | - Add target\_extension option [\#25](https://github.com/mr-doc/mr-doc/pull/25) ([llamerr](https://github.com/llamerr)) 254 | 255 | - Changed README.md and examples to include new jsFiddle option [\#22](https://github.com/mr-doc/mr-doc/pull/22) ([orweinberger](https://github.com/orweinberger)) 256 | 257 | - Added an option to include jsFiddle embed links within code comments [\#21](https://github.com/mr-doc/mr-doc/pull/21) ([orweinberger](https://github.com/orweinberger)) 258 | 259 | - Regenerating docs with unreleased version of doxx [\#20](https://github.com/mr-doc/mr-doc/pull/20) ([eddywashere](https://github.com/eddywashere)) 260 | 261 | - Update template.jade for change bootstrap urls [\#19](https://github.com/mr-doc/mr-doc/pull/19) ([wondersloth](https://github.com/wondersloth)) 262 | 263 | - Show README.md in index.html [\#17](https://github.com/mr-doc/mr-doc/pull/17) ([ilsken](https://github.com/ilsken)) 264 | 265 | - Fixes for Windows support [\#16](https://github.com/mr-doc/mr-doc/pull/16) ([itamarro](https://github.com/itamarro)) 266 | 267 | ## [v0.6.0](https://github.com/mr-doc/mr-doc/tree/v0.6.0) (2013-04-28) 268 | 269 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v0.5.9...v0.6.0) 270 | 271 | **Closed issues:** 272 | 273 | - doxx breaks, if no package.json exists [\#9](https://github.com/mr-doc/mr-doc/issues/9) 274 | 275 | **Merged pull requests:** 276 | 277 | - Fix --ignore option not being passed to collectFiles correctly [\#11](https://github.com/mr-doc/mr-doc/pull/11) ([jharwig](https://github.com/jharwig)) 278 | 279 | - Fix for Issue \#9: no package.json breaks it [\#10](https://github.com/mr-doc/mr-doc/pull/10) ([philippkemmeter](https://github.com/philippkemmeter)) 280 | 281 | - made CDN links protocol relative [\#4](https://github.com/mr-doc/mr-doc/pull/4) ([seangarner](https://github.com/seangarner)) 282 | 283 | ## [v0.5.9](https://github.com/mr-doc/mr-doc/tree/v0.5.9) (2013-02-16) 284 | 285 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v0.5.8...v0.5.9) 286 | 287 | **Fixed bugs:** 288 | 289 | - Doxx doesn't handle well multiple parameters [\#2](https://github.com/mr-doc/mr-doc/issues/2) 290 | 291 | **Merged pull requests:** 292 | 293 | - bugfix for multiple @param tags [\#3](https://github.com/mr-doc/mr-doc/pull/3) ([andban](https://github.com/andban)) 294 | 295 | - Fix crash when subdirs present in source [\#1](https://github.com/mr-doc/mr-doc/pull/1) ([seangarner](https://github.com/seangarner)) 296 | 297 | ## [v0.5.8](https://github.com/mr-doc/mr-doc/tree/v0.5.8) (2013-01-13) 298 | 299 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v0.5.7...v0.5.8) 300 | 301 | ## [v0.5.7](https://github.com/mr-doc/mr-doc/tree/v0.5.7) (2013-01-13) 302 | 303 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v0.5.6...v0.5.7) 304 | 305 | ## [v0.5.6](https://github.com/mr-doc/mr-doc/tree/v0.5.6) (2013-01-12) 306 | 307 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v0.5.5...v0.5.6) 308 | 309 | ## [v0.5.5](https://github.com/mr-doc/mr-doc/tree/v0.5.5) (2013-01-12) 310 | 311 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v0.5.4...v0.5.5) 312 | 313 | ## [v0.5.4](https://github.com/mr-doc/mr-doc/tree/v0.5.4) (2013-01-12) 314 | 315 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v0.5.3...v0.5.4) 316 | 317 | ## [v0.5.3](https://github.com/mr-doc/mr-doc/tree/v0.5.3) (2013-01-12) 318 | 319 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v0.5.2...v0.5.3) 320 | 321 | ## [v0.5.2](https://github.com/mr-doc/mr-doc/tree/v0.5.2) (2013-01-12) 322 | 323 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v0.5.1...v0.5.2) 324 | 325 | ## [v0.5.1](https://github.com/mr-doc/mr-doc/tree/v0.5.1) (2013-01-12) 326 | 327 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v0.5.0...v0.5.1) 328 | 329 | ## [v0.5.0](https://github.com/mr-doc/mr-doc/tree/v0.5.0) (2013-01-12) 330 | 331 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v0.3.3...v0.5.0) 332 | 333 | ## [v0.3.3](https://github.com/mr-doc/mr-doc/tree/v0.3.3) (2012-10-19) 334 | 335 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v0.3.2...v0.3.3) 336 | 337 | ## [v0.3.2](https://github.com/mr-doc/mr-doc/tree/v0.3.2) (2012-10-19) 338 | 339 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v0.3.1...v0.3.2) 340 | 341 | ## [v0.3.1](https://github.com/mr-doc/mr-doc/tree/v0.3.1) (2012-10-06) 342 | 343 | [Full Changelog](https://github.com/mr-doc/mr-doc/compare/v0.2.0...v0.3.1) 344 | 345 | ## [v0.2.0](https://github.com/mr-doc/mr-doc/tree/v0.2.0) (2012-09-29) 346 | 347 | 348 | 349 | \* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)* --------------------------------------------------------------------------------