diff --git a/.gitignore b/.gitignore index 929e4afa..11957985 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,10 @@ -build-files/java/build -jsdoc.jar -test/tutorials/out -conf.json -out/ +# Development-related files .tern-port +node_modules/grunt* + +# User-specific files +conf.json + +# Generated files +test/tutorials/out +out/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 25f5a19f..992136ce 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -45,9 +45,6 @@ ones. Create a separate branch for each unrelated changeset. For instance, if you're fixing a bug in the parser and adding some new UI to the default template, those should be separate branches and merge requests. - - Also, if you want to change `package.json`, note that you must make your changes - in `Jake/templates/package.json.tmpl`, then run `jake`. 5. **Add tests** Add tests for your change. If you are submitting a bugfix, include a test that diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100644 index 00000000..1ce5de2b --- /dev/null +++ b/Gruntfile.js @@ -0,0 +1,31 @@ +module.exports = function(grunt) { + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + bumpup: { + options: { + updateProps: { + pkg: 'package.json' + } + }, + setters: { + date: function(oldDate, releaseType, options) { + return oldDate; + }, + version: function(oldVersion, releaseType, options) { + return oldVersion; + }, + revision: function(oldVersion, releaseType, options) { + return String( Date.now() ); + } + }, + files: [ + 'package.json' + ] + } + }); + + grunt.loadNpmTasks('grunt-bumpup'); + grunt.renameTask('bumpup', 'bump'); + + grunt.registerTask('default', ['bump']); +}; diff --git a/Jake/lib/mustache.js b/Jake/lib/mustache.js deleted file mode 100644 index 60687a38..00000000 --- a/Jake/lib/mustache.js +++ /dev/null @@ -1,335 +0,0 @@ -/* - mustache.js — Logic-less templates in JavaScript - - See http://mustache.github.com/ for more info. -*/ - -var Mustache = function() { - var Renderer = function() {}; - - Renderer.prototype = { - otag: "{{", - ctag: "}}", - pragmas: {}, - buffer: [], - pragmas_implemented: { - "IMPLICIT-ITERATOR": true, - "ARRAY-ORDINALS": true // define #first? and #last? when looping arrays - }, - context: {}, - - render: function(template, context, partials, in_recursion) { - // reset buffer & set context - if(!in_recursion) { - this.context = context; - this.buffer = []; // TODO: make this non-lazy - } - - // fail fast - if(!this.includes("", template)) { - if(in_recursion) { - return template; - } else { - this.send(template); - return; - } - } - - template = this.render_pragmas(template); - var html = this.render_section(template, context, partials); - if(in_recursion) { - return this.render_tags(html, context, partials, in_recursion); - } - - this.render_tags(html, context, partials, in_recursion); - }, - - /* - Sends parsed lines - */ - send: function(line) { - if(line != "") { - this.buffer.push(line); - } - }, - - /* - Looks for %PRAGMAS - */ - render_pragmas: function(template) { - // no pragmas - if(!this.includes("%", template)) { - return template; - } - - var that = this; - var regex = new RegExp(this.otag + "%([\\w-]+) ?([\\w]+=[\\w]+)?" + - this.ctag); - return template.replace(regex, function(match, pragma, options) { - if(!that.pragmas_implemented[pragma]) { - throw({message: - "This implementation of mustache doesn't understand the '" + - pragma + "' pragma"}); - } - that.pragmas[pragma] = {}; - if(options) { - var opts = options.split("="); - that.pragmas[pragma][opts[0]] = opts[1]; - } - return ""; - // ignore unknown pragmas silently - }); - }, - - /* - Tries to find a partial in the curent scope and render it - */ - render_partial: function(name, context, partials) { - name = this.trim(name); - if(!partials || partials[name] === undefined) { - throw({message: "unknown_partial '" + name + "'"}); - } - if(typeof(context[name]) != "object") { - return this.render(partials[name], context, partials, true); - } - return this.render(partials[name], context[name], partials, true); - }, - - /* - Renders inverted (^) and normal (#) sections - */ - render_section: function(template, context, partials) { - if(!this.includes("#", template) && !this.includes("^", template)) { - return template; - } - - var that = this; - // CSW - Added "+?" so it finds the tighest bound, not the widest - var regex = new RegExp(this.otag + "(\\^|\\#)\\s*(.+)\\s*" + this.ctag + - "\n*([\\s\\S]+?)" + this.otag + "\\/\\s*\\2\\s*" + this.ctag + - "\\s*", "mg"); - - // for each {{#foo}}{{/foo}} section do... - return template.replace(regex, function(match, type, name, content) { - var value = that.find(name, context); - if(type == "^") { // inverted section - if(!value || that.is_array(value) && value.length === 0) { - // false or empty list, render it - return that.render(content, context, partials, true); - } else { - return ""; - } - } else if(type == "#") { // normal section - if(that.is_array(value)) { // Enumerable, Let's loop! - var len = value.length; - return value.map(function(row, i) { - return that.render(content, that.create_context(row, {first: i === 0, last: i === len-1}), - partials, true); - }).join(""); - } else if(that.is_object(value)) { // Object, Use it as subcontext! - return that.render(content, that.create_context(value), - partials, true); - } else if(typeof value === "function") { - // higher order section - return value.call(context, content, function(text) { - return that.render(text, context, partials, true); - }); - } else if(value) { // boolean section - return that.render(content, context, partials, true); - } else { - return ""; - } - } - }); - }, - - /* - Replace {{foo}} and friends with values from our view - */ - render_tags: function(template, context, partials, in_recursion) { - // tit for tat - var that = this; - - var new_regex = function() { - return new RegExp(that.otag + "(=|!|>|\\{|%)?([^\\/#\\^]+?)\\1?" + - that.ctag + "+", "g"); - }; - - var regex = new_regex(); - var tag_replace_callback = function(match, operator, name) { - switch(operator) { - case "!": // ignore comments - return ""; - case "=": // set new delimiters, rebuild the replace regexp - that.set_delimiters(name); - regex = new_regex(); - return ""; - case ">": // render partial - return that.render_partial(name, context, partials); - case "{": // the triple mustache is unescaped - return that.find(name, context); - default: // escape the value - return that.escape(that.find(name, context)); - } - }; - var lines = template.split("\n"); - for(var i = 0; i < lines.length; i++) { - lines[i] = lines[i].replace(regex, tag_replace_callback, this); - if(!in_recursion) { - this.send(lines[i]); - } - } - - if(in_recursion) { - return lines.join("\n"); - } - }, - - set_delimiters: function(delimiters) { - var dels = delimiters.split(" "); - this.otag = this.escape_regex(dels[0]); - this.ctag = this.escape_regex(dels[1]); - }, - - escape_regex: function(text) { - // thank you Simon Willison - if(!arguments.callee.sRE) { - var specials = [ - '/', '.', '*', '+', '?', '|', - '(', ')', '[', ']', '{', '}', '\\' - ]; - arguments.callee.sRE = new RegExp( - '(\\' + specials.join('|\\') + ')', 'g' - ); - } - return text.replace(arguments.callee.sRE, '\\$1'); - }, - - /* - find `name` in current `context`. That is find me a value - from the view object - */ - find: function(name, context) { - name = this.trim(name); - - // Checks whether a value is thruthy or false or 0 - function is_kinda_truthy(bool) { - return bool === false || bool === 0 || bool; - } - - var value; - if(is_kinda_truthy(context[name])) { - value = context[name]; - } else if(is_kinda_truthy(this.context[name])) { - value = this.context[name]; - } - - if(typeof value === "function") { - return value.apply(context); - } - if(value !== undefined) { - return value; - } - // silently ignore unkown variables - return ""; - }, - - // Utility methods - - /* includes tag */ - includes: function(needle, haystack) { - return haystack.indexOf(this.otag + needle) != -1; - }, - - /* - Does away with nasty characters - */ - escape: function(s) { - s = String(s === null ? "" : s); - return s.replace(/&(?!\w+;)|["'<>\\]/g, function(s) { - switch(s) { - case "&": return "&"; - case "\\": return "\\\\"; - case '"': return '"'; - case "'": return '''; - case "<": return "<"; - case ">": return ">"; - default: return s; - } - }); - }, - - // by @langalex, support for arrays of strings - create_context: function(_context, opts) { - if(this.is_object(_context)) { - if (this.pragmas["ARRAY-ORDINALS"] && opts) { - _context['first?'] = opts.first || false; - _context['last?'] = opts.last || false; - } - return _context; - } else { - var iterator = "."; - if(this.pragmas["IMPLICIT-ITERATOR"]) { - iterator = this.pragmas["IMPLICIT-ITERATOR"].iterator; - } - var ctx = {}; - ctx[iterator] = _context; - if (this.pragmas["ARRAY-ORDINALS"] && opts){ - ctx['first?'] = opts.first || false; - ctx['last?'] = opts.last || false; - } - return ctx; - } - }, - - is_object: function(a) { - return a && typeof a == "object"; - }, - - is_array: function(a) { - return Object.prototype.toString.call(a) === '[object Array]'; - }, - - /* - Gets rid of leading and trailing whitespace - */ - trim: function(s) { - return s.replace(/^\s*|\s*$/g, ""); - }, - - /* - Why, why, why? Because IE. Cry, cry cry. - */ - map: function(array, fn) { - if (typeof array.map == "function") { - return array.map(fn); - } else { - var r = []; - var l = array.length; - for(var i = 0; i < l; i++) { - r.push(fn(array[i])); - } - return r; - } - } - }; - - return({ - name: "mustache.js", - version: "0.3.1-dev", - - /* - Turns a template and view into HTML - */ - to_html: function(template, view, partials, send_fun) { - var renderer = new Renderer(); - if(send_fun) { - renderer.send = send_fun; - } - renderer.render(template, view, partials); - if(!send_fun) { - return renderer.buffer.join("\n"); - } - } - }); -}(); \ No newline at end of file diff --git a/Jake/templates/package.json.tmpl b/Jake/templates/package.json.tmpl deleted file mode 100644 index 8a4f4ae5..00000000 --- a/Jake/templates/package.json.tmpl +++ /dev/null @@ -1,54 +0,0 @@ -{ - "name": "{{appname}}", - "version": "{{appversion}}", - "revision": "{{timestamp}}", - "description": "An API documentation generator for JavaScript.", - "keywords": [ "documentation", "javascript" ], - "licenses": [ - { - "type": "Apache 2.0", - "url": "http://www.apache.org/licenses/LICENSE-2.0" - } - ], - "repository": { - "type": "git", - "url": "https://github.com/jsdoc3/jsdoc" - }, - "dependencies": { - "async": "0.1.22", - "catharsis": "0.7.0", - "esprima": "1.0.4", - "js2xmlparser": "0.1.0", - "marked": "0.2.8", - "taffydb": "git+https://github.com/hegemonic/taffydb.git", - "underscore": "1.4.2", - "wrench": "1.3.9" - }, - "devDependencies": { - "jshint": "2.3.0", - "tv4": "git+https://github.com/hegemonic/tv4.git#own-properties" - }, - "engines": { - "node": ">=0.10" - }, - "scripts": { - "postinstall": "node ./node/postinstall.js" - }, - "bin": { - "jsdoc": "./jsdoc.js" - }, - "bugs": "https://github.com/jsdoc3/jsdoc/issues", - "author": { - "name": "Michael Mathews", - "email": "micmath@gmail.com" - }, - "contributors": [ - { - "url": "https://github.com/jsdoc3/jsdoc/graphs/contributors" - } - ], - "maintainers": { - "name": "Jeff Williams", - "email": "jeffrey.l.williams@gmail.com" - } -} diff --git a/Jakefile.js b/Jakefile.js deleted file mode 100644 index ab5969d7..00000000 --- a/Jakefile.js +++ /dev/null @@ -1,82 +0,0 @@ -/*global desc: true, fail: true, Mustache: true, task: true */ -// see: https://github.com/mde/jake - -desc('Updating package.json revision.'); -task('default', [], function(params) { - /*jshint evil: true */ - var fs = require('fs'); - - // import the Mustache template tool - eval(fs.readFileSync('Jake/lib/mustache.js', 'utf8')); - - var templates = { - packagejson : fs.readFileSync('Jake/templates/package.json.tmpl', 'utf8') - }; - - var metadata = { - appname : 'jsdoc', - appversion : '3.3.0-dev', - timestamp : '' + new Date().getTime() - }; - - var outdir = './'; - - var rendered = Mustache.to_html(templates.packagejson, metadata); - - fs.writeFileSync(outdir + 'package.json', rendered, 'utf8'); - - process.exit(0); - -}); - -desc('Installs a plugin/template.'); -task('install', [], function(loc) { - var fs = require('fs'), - util = require('util'), - path = require('path'), - wrench = require('wrench'); - - if(!loc) { - fail("You must specify the location of the plugin/template."); - } - - if(!fs.existsSync(loc)) { - fail("plugin/template location [" + loc + "] is not valid."); - } - - var pluginLoc = path.join(loc, "plugins"), - templateLoc = path.join(loc, "templates"), - jsdocLoc = process.cwd(), - name, - config; - - //First the plugin - if(fs.existsSync(pluginLoc)) { - //copy it over - wrench.copyDirSyncRecursive(pluginLoc, path.join(jsdocLoc, "plugins"), { - preserve : true - }); - //find out what it's called - name = fs.readdirSync(pluginLoc)[0].replace(".js", ""); - //And finally edit the conf.json - try { - config = JSON.parse(fs.readFileSync(path.join(jsdocLoc, 'conf.json'), 'utf8')); - if(config.plugins.indexOf('plugins/' + name) == -1) { - config.plugins.push('plugins/' + name); - fs.writeFileSync(path.join(jsdocLoc, 'conf.json'), JSON.stringify(config, null, " "), 'utf8'); - } - } catch (e) { - fail("Could not edit the conf.json file: " + e); - } - } - - //Then the template - if(fs.existsSync(templateLoc)) { - wrench.copyDirSyncRecursive(templateLoc, path.join(jsdocLoc, "templates"), { - preserve : true - }); - } - - process.exit(0); - -}); \ No newline at end of file diff --git a/package.json b/package.json index ca0bf005..dfdf79bb 100644 --- a/package.json +++ b/package.json @@ -1,18 +1,21 @@ { "name": "jsdoc", "version": "3.3.0-dev", - "revision": "1387936297601", + "revision": "1387991255485", "description": "An API documentation generator for JavaScript.", - "keywords": [ "documentation", "javascript" ], + "keywords": [ + "documentation", + "javascript" + ], "licenses": [ { "type": "Apache 2.0", - "url": "http://www.apache.org/licenses/LICENSE-2.0" + "url": "http://www.apache.org/licenses/LICENSE-2.0" } ], "repository": { "type": "git", - "url": "https://github.com/jsdoc3/jsdoc" + "url": "https://github.com/jsdoc3/jsdoc" }, "dependencies": { "async": "0.1.22", @@ -20,11 +23,13 @@ "esprima": "1.0.4", "js2xmlparser": "0.1.0", "marked": "0.2.8", - "taffydb": "git+https://github.com/hegemonic/taffydb.git", + "taffydb": "git+https://github.com/hegemonic/taffydb.git", "underscore": "1.4.2", - "wrench": "1.3.9" + "wrench": "1.3.9" }, "devDependencies": { + "grunt": "~0.4.2", + "grunt-bumpup": "~0.4.2", "jshint": "2.3.0", "tv4": "git+https://github.com/hegemonic/tv4.git#own-properties" }, @@ -39,7 +44,7 @@ }, "bugs": "https://github.com/jsdoc3/jsdoc/issues", "author": { - "name": "Michael Mathews", + "name": "Michael Mathews", "email": "micmath@gmail.com" }, "contributors": [