diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b67fcd1..cc659ad0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # apiDoc Changelog +#### 0.2.0 +Extend `@apiParam`, `@apiSuccess`, `@apiError` with a grouping ability. Example `@apiParam (group) varname`. +view [@apiParam](http://apidocjs.com/#param-api-param) +Add new Functions: +* [@apiParamTitle](http://apidocjs.com/#param-api-param-title) +* [@apiSuccessTitle](http://apidocjs.com/#param-api-success-title) +* [@apiErrorTitle](http://apidocjs.com/#param-api-error-title) +Minor Template-Bugfixes. + #### 0.1.11 Allow whitespace in apiName and apiGroup. Bugfix filter for directories. @@ -18,7 +27,7 @@ Fix for whitespace before comment block (Brandon Hamilton https://github.com/api Change templates, enable navigation scroll. #### 0.1.7 -Add [@apiIgnore`](http://apidocjs.com/#param-api-ignore). +Add [@apiIgnore](http://apidocjs.com/#param-api-ignore). Update grunt Modules. #### 0.1.6 diff --git a/lib/apidoc.js b/lib/apidoc.js index 12a32151..3234971e 100644 --- a/lib/apidoc.js +++ b/lib/apidoc.js @@ -90,24 +90,32 @@ var app = { apierror : "./plugins/parser_api_error.js", apierrorexample : "./plugins/parser_api_error_example.js", apierrorstructure : "./plugins/parser_api_error_structure.js", + apierrortitle : "./plugins/parser_api_error_title.js", apiexample : "./plugins/parser_api_example.js", apigroup : "./plugins/parser_api_group.js", apiinfo : "./plugins/parser_api_info.js", apiinfoexample : "./plugins/parser_api_info_example.js", + apiinfotitle : "./plugins/parser_api_info_title.js", apiname : "./plugins/parser_api_name.js", apiparam : "./plugins/parser_api_param.js", + apiparamtitle : "./plugins/parser_api_param_title.js", apipermission : "./plugins/parser_api_permission.js", apistructure : "./plugins/parser_api_structure.js", apisuccess : "./plugins/parser_api_success.js", apisuccessexample : "./plugins/parser_api_success_example.js", apisuccessstructure : "./plugins/parser_api_success_structure.js", + apisuccesstitle : "./plugins/parser_api_success_title.js", apiversion : "./plugins/parser_api_version.js" }, workers: { workererrorstructure : "./plugins/worker_error_structure.js", + workererrortitle : "./plugins/worker_error_title.js", + workerinfotitle : "./plugins/worker_info_title.js", workerpermission : "./plugins/worker_permission.js", workerstructure : "./plugins/worker_structure.js", - workersuccessstructure : "./plugins/worker_success_structure.js" + workerparamtitle : "./plugins/worker_param_title.js", + workersuccessstructure : "./plugins/worker_success_structure.js", + workersuccesstitle : "./plugins/worker_success_title.js" } }; // app @@ -183,7 +191,8 @@ function createOutputFiles(parsedFiles, parsedFilenames, packageInfos) for(var blockIndex = 0; blockIndex < parsedFile.length; blockIndex += 1) { var block = parsedFile[blockIndex]; - if(Object.keys(block.global).length === 0 && Object.keys(block.local).length > 0) + // "<= 1" if successTitle gets removed, empty Object remain. + if(Object.keys(block.global).length <= 1 && Object.keys(block.local).length > 0) { // Add needed Elements for sorting if( ! block.local.group) block.local.group = path.basename( parsedFilenames[fileIndex] ); diff --git a/lib/parser.js b/lib/parser.js index 446580d1..0ab91481 100644 --- a/lib/parser.js +++ b/lib/parser.js @@ -135,7 +135,7 @@ Parser.prototype._parseBlockElements = function(indexApiBlocks, detectedElements if(Object.keys(blockData.global).length > 0) { throw new Error("Can't set \"@" + element.sourceName + "\" in file \"" + self.filename + - "\" block number " + (blockIndex + 1) + ", only one define or use is allowed in the same block." + "\" block number " + (blockIndex + 1) + ", only one definition or use is allowed in the same block." ); } } @@ -147,18 +147,23 @@ Parser.prototype._parseBlockElements = function(indexApiBlocks, detectedElements // Only one global allowed per block if(pushTo === "global" || pushTo.substr(0, 7) === "global.") { - if(Object.keys(blockData.global).length > 0) - { - throw new Error("Can't set \"@" + element.sourceName + "\" in file \"" + self.filename + - "\" block number " + (blockIndex + 1) + ", only one define per block allowed." - ); - } + var allowMultiple = self.parsers[element.name].allowMultiple || false; - if(preventGlobal === true) + if( ! allowMultiple) { - throw new Error("Can't set \"@" + element.sourceName + "\" in file \"" + self.filename + - "\" block number " + (blockIndex + 1) + ", only one define or use is allowed in the same block." - ); + if(Object.keys(blockData.global).length > 0) + { + throw new Error("Can't set \"@" + element.sourceName + "\" in file \"" + self.filename + + "\" block number " + (blockIndex + 1) + ", only one definition per block allowed." + ); + } + + if(preventGlobal === true) + { + throw new Error("Can't set \"@" + element.sourceName + "\" in file \"" + self.filename + + "\" block number " + (blockIndex + 1) + ", only one definition or use is allowed in the same block." + ); + } } } diff --git a/lib/plugins/filter_api_error.js b/lib/plugins/filter_api_error.js index eecda0f2..130f70f8 100644 --- a/lib/plugins/filter_api_error.js +++ b/lib/plugins/filter_api_error.js @@ -10,7 +10,7 @@ var filterApiParam = require("./filter_api_param.js"); */ function postFilter(parsedFiles, filenames) { - filterApiParam._postFilter(parsedFiles, filenames, "error"); + filterApiParam.postFilter(parsedFiles, filenames, "error"); } // postFilter /** diff --git a/lib/plugins/filter_api_info.js b/lib/plugins/filter_api_info.js index 2ea84d7c..d32d7f4e 100644 --- a/lib/plugins/filter_api_info.js +++ b/lib/plugins/filter_api_info.js @@ -10,7 +10,7 @@ var filterApiParam = require("./filter_api_param.js"); */ function postFilter(parsedFiles, filenames) { - filterApiParam._postFilter(parsedFiles, filenames, "info"); + filterApiParam.postFilter(parsedFiles, filenames, "info"); } // postFilter /** diff --git a/lib/plugins/filter_api_param.js b/lib/plugins/filter_api_param.js index af0007db..d5915ee7 100644 --- a/lib/plugins/filter_api_param.js +++ b/lib/plugins/filter_api_param.js @@ -1,15 +1,3 @@ -/** - * Post Filter parsed results. - * - * @param {Object[]} parsedFiles - * @param {String[]} filenames - * @returns {Object} - */ -function postFilter(parsedFiles, filenames) -{ - _postFilter(parsedFiles, filenames, "parameter"); -} // postFilter - /** * Post Filter parsed results. * @@ -19,8 +7,9 @@ function postFilter(parsedFiles, filenames) * @returns {Object} * @todo Use elegant Map and Reduce Funktions. */ -function _postFilter(parsedFiles, filenames, tagName) +function postFilter(parsedFiles, filenames, tagName) { + tagName = tagName || "parameter"; for(var fileIndex = 0; fileIndex < parsedFiles.length; fileIndex += 1) { var parsedFile = parsedFiles[fileIndex]; @@ -29,29 +18,34 @@ function _postFilter(parsedFiles, filenames, tagName) var block = parsedFile[blockIndex]; if(block["local"][tagName] && block["local"][tagName]["fields"]) { - // Remove double field params, 1st is newest and is ok - var fields = block["local"][tagName]["fields"]; - var newFields = []; - var keys = {}; - for(var fieldIndex = 0; fieldIndex < fields.length; fieldIndex += 1) + var blockFields = block["local"][tagName]["fields"]; + var blockFieldKeys = Object.keys(blockFields); + for(var blockFieldKeysIndex = 0; blockFieldKeysIndex < blockFieldKeys.length; blockFieldKeysIndex += 1) { - var key = fields[fieldIndex].field; - if( ! keys[key]) + var blockFieldKey = blockFieldKeys[blockFieldKeysIndex]; + // Remove double field params, 1st is newest and is ok + var fields = block["local"][tagName]["fields"][blockFieldKey]; + var newFields = []; + var keys = {}; + for(var fieldIndex = 0; fieldIndex < fields.length; fieldIndex += 1) { - keys[key] = 1; - newFields.push(fields[fieldIndex]); - } - } // for fieldIndex - block["local"][tagName]["fields"] = newFields; + var key = fields[fieldIndex].field; + if( ! keys[key]) + { + keys[key] = 1; + newFields.push(fields[fieldIndex]); + } + } // for fieldIndex + block["local"][tagName]["fields"][blockFieldKey] = newFields; + } // for blockFieldKeysIndex } } // for blockIndex } // for fileIndex -} // _postFilter +} // postFilter /** * Exports. */ module.exports = { - postFilter: postFilter, - _postFilter: _postFilter + postFilter: postFilter }; \ No newline at end of file diff --git a/lib/plugins/filter_api_success.js b/lib/plugins/filter_api_success.js index 1e103011..2047fff4 100644 --- a/lib/plugins/filter_api_success.js +++ b/lib/plugins/filter_api_success.js @@ -10,7 +10,7 @@ var filterApiParam = require("./filter_api_param.js"); */ function postFilter(parsedFiles, filenames) { - filterApiParam._postFilter(parsedFiles, filenames, "success"); + filterApiParam.postFilter(parsedFiles, filenames, "success"); } // postFilter /** diff --git a/lib/plugins/parser_api_error.js b/lib/plugins/parser_api_error.js index 299bef2d..43cefd8d 100644 --- a/lib/plugins/parser_api_error.js +++ b/lib/plugins/parser_api_error.js @@ -1,15 +1,20 @@ // Same as @apiparam var apiParam = require("./parser_api_param.js"); +function parse(content, source) +{ + return apiParam.parse(content, source, "Error 4xx"); +} + function pushTo() { - return "local.error.fields"; + return "local.error.fields." + apiParam.getGroup(); } /** * Exports. */ module.exports = { - parse: apiParam.parse, + parse: parse, pushTo: pushTo }; \ No newline at end of file diff --git a/lib/plugins/parser_api_error_title.js b/lib/plugins/parser_api_error_title.js new file mode 100644 index 00000000..944effa7 --- /dev/null +++ b/lib/plugins/parser_api_error_title.js @@ -0,0 +1,21 @@ +var apiParser = require("./parser_api_param_title.js"); + +function parse(content, source) +{ + return apiParser.parse(content, source); +} // parse + +function pushTo() +{ + return "global.errorTitle"; +} + +/** + * Exports. + */ +module.exports = { + parse: parse, + pushTo: pushTo, + getGroup: apiParser.getGroup, + allowMultiple: true +}; \ No newline at end of file diff --git a/lib/plugins/parser_api_info.js b/lib/plugins/parser_api_info.js index f55e45be..fa6f5f6d 100644 --- a/lib/plugins/parser_api_info.js +++ b/lib/plugins/parser_api_info.js @@ -1,15 +1,20 @@ // Same as @apiparam var apiParam = require("./parser_api_param.js"); +function parse(content, source) +{ + return apiParam.parse(content, source, "Info"); +} + function pushTo() { - return "local.info.fields"; + return "local.info.fields." + apiParam.getGroup(); } /** * Exports. */ module.exports = { - parse: apiParam.parse, + parse: parse, pushTo: pushTo }; \ No newline at end of file diff --git a/lib/plugins/parser_api_info_title.js b/lib/plugins/parser_api_info_title.js new file mode 100644 index 00000000..f440900c --- /dev/null +++ b/lib/plugins/parser_api_info_title.js @@ -0,0 +1,21 @@ +var apiParser = require("./parser_api_param_title.js"); + +function parse(content, source) +{ + return apiParser.parse(content, source); +} // parse + +function pushTo() +{ + return "global.infoTitle"; +} + +/** + * Exports. + */ +module.exports = { + parse: parse, + pushTo: pushTo, + getGroup: apiParser.getGroup, + allowMultiple: true +}; \ No newline at end of file diff --git a/lib/plugins/parser_api_param.js b/lib/plugins/parser_api_param.js index 2515edf5..3df178e1 100644 --- a/lib/plugins/parser_api_param.js +++ b/lib/plugins/parser_api_param.js @@ -1,4 +1,6 @@ -function parse(content) +var group = ""; + +function parse(content, source, defaultGroup) { // Trim content = content.replace(/^\s+|\s+$/g, ""); @@ -6,11 +8,16 @@ function parse(content) // Replace Linebreak with Unicode content = content.replace(/\n/g, "\uffff"); - // Search: type, field, defaultValue, optional, description + // Search: group, type, field, defaultValue, optional, description // Example: {Boolean} [user.name="Default Value"] Users lastname. // RegExp: // ^ // (?: + // (?:\( + // (.+?) ; group + // \)) + // \s*)? + // (?: // (?:\{ // (.+?) ; type // \}) @@ -24,8 +31,7 @@ function parse(content) // \s* // (.*)? ; description // (^@|$) ; Multiline - //var parseRegExp = /^(?:(?:\{(.+?)\})\s*)?(\[?(\S[a-zA-Z0-9._\-]*)(?:=['|"]?([\s.a-zA-Z0-9_\-]*)['|"]?)?\]?)\s*(.*)?$/g; - var parseRegExp = /^(?:(?:\{(.+?)\})\s*)?(\[?(\S[a-zA-Z0-9._\-]*)(?:=['|"]?([\s.a-zA-Z0-9_\-]*)['|"]?)?\]?)\s*(.*)?(^@|$)/g; + var parseRegExp = /^(?:(?:\((.+?)\))\s*)?(?:(?:\{(.+?)\})\s*)?(\[?(\S[a-zA-Z0-9._\-]*)(?:=['|"]?([\s.a-zA-Z0-9_\-]*)['|"]?)?\]?)\s*(.*)?(^@|$)/g; var matches = parseRegExp.exec(content); // function objectValuesToString(obj) // { @@ -67,20 +73,28 @@ function parse(content) if( ! matches) return null; // Reverse Unicode Linebreaks - if(matches[5]) matches[5] = matches[5].replace(/\uffff/g, "\n"); + if(matches[6]) matches[6] = matches[6].replace(/\uffff/g, "\n"); + + group = matches[1] || defaultGroup || "Parameter"; return { - type: matches[1], - field: matches[3], - defaultValue: matches[4], - optional: (matches[2] !== matches[3]) ? true : false, - description: matches[5] + group: group, + type: matches[2], + field: matches[4], + defaultValue: matches[5], + optional: (matches[3] !== matches[4]) ? true : false, + description: matches[6] || "" }; } // parse function pushTo() { - return "local.parameter.fields"; + return "local.parameter.fields." + getGroup(); +} + +function getGroup() +{ + return group; } /** @@ -88,5 +102,6 @@ function pushTo() */ module.exports = { parse: parse, - pushTo: pushTo + pushTo: pushTo, + getGroup: getGroup }; \ No newline at end of file diff --git a/lib/plugins/parser_api_param_title.js b/lib/plugins/parser_api_param_title.js new file mode 100644 index 00000000..64a27ab4 --- /dev/null +++ b/lib/plugins/parser_api_param_title.js @@ -0,0 +1,41 @@ +var group = ""; + +function parse(content, source) +{ + // Trim + content = content.replace(/^\s+|\s+$/g, ""); + + // Replace Linebreak with Unicode + content = content.replace(/\n/g, "\uffff"); + + // Search: group, title + var parseRegExp = /^(?:\((.+?)\))\s*(.*)(^@|$)/g; + var matches = parseRegExp.exec(content); + + if( ! matches) return null; + + return { + group: matches[1], + title: matches[2] + }; +} // parse + +function pushTo() +{ + return "global.paramTitle"; +} + +function getGroup() +{ + return group; +} + +/** + * Exports. + */ +module.exports = { + parse: parse, + pushTo: pushTo, + getGroup: getGroup, + allowMultiple: true +}; \ No newline at end of file diff --git a/lib/plugins/parser_api_success.js b/lib/plugins/parser_api_success.js index 900f33e0..403bc645 100644 --- a/lib/plugins/parser_api_success.js +++ b/lib/plugins/parser_api_success.js @@ -1,15 +1,20 @@ // Same as @apiparam var apiParam = require("./parser_api_param.js"); +function parse(content, source) +{ + return apiParam.parse(content, source, "Success 200"); +} + function pushTo() { - return "local.success.fields"; + return "local.success.fields." + apiParam.getGroup(); } /** * Exports. */ module.exports = { - parse: apiParam.parse, + parse: parse, pushTo: pushTo }; \ No newline at end of file diff --git a/lib/plugins/parser_api_success_title.js b/lib/plugins/parser_api_success_title.js new file mode 100644 index 00000000..df0363f2 --- /dev/null +++ b/lib/plugins/parser_api_success_title.js @@ -0,0 +1,21 @@ +var apiParser = require("./parser_api_param_title.js"); + +function parse(content, source) +{ + return apiParser.parse(content, source); +} // parse + +function pushTo() +{ + return "global.successTitle"; +} + +/** + * Exports. + */ +module.exports = { + parse: parse, + pushTo: pushTo, + getGroup: apiParser.getGroup, + allowMultiple: true +}; \ No newline at end of file diff --git a/lib/plugins/worker_error_structure.js b/lib/plugins/worker_error_structure.js index f0b370b7..e3f23724 100644 --- a/lib/plugins/worker_error_structure.js +++ b/lib/plugins/worker_error_structure.js @@ -9,7 +9,7 @@ var apiWorker = require("./worker_structure.js"); */ function preProcess(parsedFiles, filenames) { - return apiWorker._preProcess(parsedFiles, filenames, "errorStructure", "defineErrorStructure"); + return apiWorker.preProcess(parsedFiles, filenames, "errorStructure", "defineErrorStructure"); } // preProcess /** @@ -21,7 +21,7 @@ function preProcess(parsedFiles, filenames) */ function postProcess(parsedFiles, filenames, preProcessResults) { - apiWorker._postProcess(parsedFiles, filenames, preProcessResults, "errorStructure", "defineErrorStructure"); + apiWorker.postProcess(parsedFiles, filenames, preProcessResults, "errorStructure", "defineErrorStructure"); } // postProcess /** diff --git a/lib/plugins/worker_error_title.js b/lib/plugins/worker_error_title.js new file mode 100644 index 00000000..e889abbf --- /dev/null +++ b/lib/plugins/worker_error_title.js @@ -0,0 +1,33 @@ +var apiWorker = require("./worker_param_title.js"); + +/** + * PreProcess. + * + * @param {Object[]} parsedFiles + * @param {String[]} filenames + * @returns {Object} + */ +function preProcess(parsedFiles, filenames) +{ + return apiWorker.preProcess(parsedFiles, filenames, "errorTitle"); +} // preProcess + +/** + * PostProcess. + * + * @param {Object[]} parsedFiles + * @param {String[]} filenames + * @param {Object[]} preProcessResults + */ +function postProcess(parsedFiles, filenames, preProcessResults) +{ + apiWorker.postProcess(parsedFiles, filenames, preProcessResults, "error", "errorTitle"); +} // postProcess + +/** + * Exports. + */ +module.exports = { + preProcess: preProcess, + postProcess: postProcess, +}; \ No newline at end of file diff --git a/lib/plugins/worker_info_title.js b/lib/plugins/worker_info_title.js new file mode 100644 index 00000000..c1d89fc3 --- /dev/null +++ b/lib/plugins/worker_info_title.js @@ -0,0 +1,33 @@ +var apiWorker = require("./worker_param_title.js"); + +/** + * PreProcess. + * + * @param {Object[]} parsedFiles + * @param {String[]} filenames + * @returns {Object} + */ +function preProcess(parsedFiles, filenames) +{ + return apiWorker.preProcess(parsedFiles, filenames, "infoTitle"); +} // preProcess + +/** + * PostProcess. + * + * @param {Object[]} parsedFiles + * @param {String[]} filenames + * @param {Object[]} preProcessResults + */ +function postProcess(parsedFiles, filenames, preProcessResults) +{ + apiWorker.postProcess(parsedFiles, filenames, preProcessResults, "info", "infoTitle"); +} // postProcess + +/** + * Exports. + */ +module.exports = { + preProcess: preProcess, + postProcess: postProcess, +}; \ No newline at end of file diff --git a/lib/plugins/worker_param_title.js b/lib/plugins/worker_param_title.js new file mode 100644 index 00000000..b0d39edc --- /dev/null +++ b/lib/plugins/worker_param_title.js @@ -0,0 +1,89 @@ +/** + * PreProcess. + * + * @param {Object[]} parsedFiles + * @param {String[]} filenames + * @returns {Object} + */ +function preProcess(parsedFiles, filenames, defineStructureName) +{ + var result = {}; + defineStructureName = defineStructureName || "paramTitle"; + result[defineStructureName] = []; + for(var fileIndex = 0; fileIndex < parsedFiles.length; fileIndex += 1) + { + var parsedFile = parsedFiles[fileIndex]; + for(var blockIndex = 0; blockIndex < parsedFile.length; blockIndex += 1) + { + var block = parsedFile[blockIndex]; + if(block["global"][defineStructureName]) + { + var entries = block["global"][defineStructureName]; + // Simple append, same Codes too. + for(var entryIndex = 0; entryIndex < entries.length; entryIndex += 1) + { + result[defineStructureName].push(entries[entryIndex]); + } // for entryIndex + + // Unset + delete(block["global"][defineStructureName]); + } + } // for blockIndex + } // for fileIndex + return result; +} // preProcess + +/** + * PostProcess. + * + * @param {Object[]} parsedFiles + * @param {String[]} filenames + * @param {Object[]} preProcessResults + */ +function postProcess(parsedFiles, filenames, preProcessResults, structureName, defineStructureName) +{ + structureName = structureName || "parameter"; + defineStructureName = defineStructureName || "paramTitle"; + for(var fileIndex = 0; fileIndex < parsedFiles.length; fileIndex += 1) + { + var parsedFile = parsedFiles[fileIndex]; + for(var blockIndex = 0; blockIndex < parsedFile.length; blockIndex += 1) + { + var block = parsedFile[blockIndex]; + if(block["local"][structureName] && block["local"][structureName]["fields"]) + { + var fields = block["local"][structureName]["fields"]; + var newBlock = {}; // preserve sorting + var blockKeys = Object.keys(fields); + for(var blockKeyIndex = 0; blockKeyIndex < blockKeys.length; blockKeyIndex += 1) + { + var blockKey = blockKeys[blockKeyIndex]; + var blockEntries = block["local"][structureName]["fields"][blockKey]; + var found = false; + for(var preIndex = 0; preIndex < preProcessResults[defineStructureName].length; preIndex += 1) + { + var preEntry = preProcessResults[defineStructureName][preIndex]; + if(preEntry.group === blockKey) + { + found = true; + newBlock[preEntry.title] = blockEntries; + } + } // for preIndex + if( ! found) + { + newBlock[blockKey] = blockEntries; + } + } // for blockKey + block["local"][structureName]["fields"] = newBlock; + } + } // for blockIndex + } // for fileIndex +} // postProcess + +/** + * Exports. + */ +module.exports = { + preProcess: preProcess, + postProcess: postProcess, +}; \ No newline at end of file diff --git a/lib/plugins/worker_permission.js b/lib/plugins/worker_permission.js index b1726325..96e3f787 100644 --- a/lib/plugins/worker_permission.js +++ b/lib/plugins/worker_permission.js @@ -1,30 +1,6 @@ var _ = require("lodash"); // Because of _.merge var semver = require("semver"); -/** - * PreProcess. - * - * @param {Object[]} parsedFiles - * @param {String[]} filenames - * @returns {Object} - */ -function preProcess(parsedFiles, filenames) -{ - return _preProcess(parsedFiles, filenames, "permission", "definePermission"); -} // preProcess - -/** - * PostProcess. - * - * @param {Object[]} parsedFiles - * @param {String[]} filenames - * @param {Object[]} preProcessResults - */ -function postProcess(parsedFiles, filenames, preProcessResults) -{ - _postProcess(parsedFiles, filenames, preProcessResults, "permission", "definePermission"); -} // postProcess - /** * PreProcess. * @@ -34,8 +10,10 @@ function postProcess(parsedFiles, filenames, preProcessResults) * @param {String} defineName * @returns {Object} */ -function _preProcess(parsedFiles, filenames, useName, defineName) +function preProcess(parsedFiles, filenames, useName, defineName) { + useName = useName || "permission"; + defineName = defineName || "definePermission"; var result = {}; for(var fileIndex = 0; fileIndex < parsedFiles.length; fileIndex += 1) { @@ -53,13 +31,14 @@ function _preProcess(parsedFiles, filenames, useName, defineName) version = block.version; } - if( ! result[name]) result[name] = {}; - result[name][version] = block["global"][defineName]; + if( ! result[defineName]) result[defineName] = {}; + if( ! result[defineName][name]) result[defineName][name] = {}; + result[defineName][name][version] = block["global"][defineName]; } } // for blockIndex } // for fileIndex return result; -} // _preProcess +} // preProcess /** * PostProcess. @@ -70,8 +49,10 @@ function _preProcess(parsedFiles, filenames, useName, defineName) * @param {String} findName * @param {String} defineName */ -function _postProcess(parsedFiles, filenames, preProcessResults, findName, defineName) +function postProcess(parsedFiles, filenames, preProcessResults, findName, defineName) { + findName = findName || "permission"; + defineName = defineName || "definePermission"; for(var fileIndex = 0; fileIndex < parsedFiles.length; fileIndex += 1) { var parsedFile = parsedFiles[fileIndex]; @@ -88,14 +69,14 @@ function _postProcess(parsedFiles, filenames, preProcessResults, findName, defin version = block.version; } - if(preProcessResults[name]) + if(preProcessResults[defineName][name]) { var matchedData = {}; var matchedVersion = version; - if(preProcessResults[name][version]) + if(preProcessResults[defineName][name][version]) { // Exact Version - matchedData = preProcessResults[name][version]; + matchedData = preProcessResults[defineName][name][version]; } else { @@ -103,7 +84,7 @@ function _postProcess(parsedFiles, filenames, preProcessResults, findName, defin var foundIndex = -1; var lastVersion = "0.0.0"; - var versionKeys = Object.keys(preProcessResults[name]); + var versionKeys = Object.keys(preProcessResults[defineName][name]); for(var versionIndex = 0; versionIndex < versionKeys.length; versionIndex += 1) { var currentVersion = versionKeys[versionIndex]; @@ -122,7 +103,7 @@ function _postProcess(parsedFiles, filenames, preProcessResults, findName, defin ); } var versionName = versionKeys[foundIndex]; - matchedData = preProcessResults[name][versionName]; + matchedData = preProcessResults[defineName][name][versionName]; } // Copy matched elements into parsed block @@ -138,33 +119,12 @@ function _postProcess(parsedFiles, filenames, preProcessResults, findName, defin } } // for blockIndex } // for fileIndex -} // _postProcess - -/** - * Recursive Merge of Objects with Arrays. - * - * @param block - * @param matchedData - * @todo Bad Hack - watch for something better - */ -function _recursiveMerge(block, matchedData) -{ - _.merge(block, matchedData, function(a, b) { - if(a instanceof Array) return a.concat(b); - if(_.isObject(a)) - { - return _recursiveMerge(a, b); - } - return a; - }); -} // _recursiveMerge +} // postProcess /** * Exports. */ module.exports = { preProcess: preProcess, - postProcess: postProcess, - _preProcess: _preProcess, - _postProcess: _postProcess + postProcess: postProcess }; \ No newline at end of file diff --git a/lib/plugins/worker_structure.js b/lib/plugins/worker_structure.js index 5bcd6c19..39d999ec 100644 --- a/lib/plugins/worker_structure.js +++ b/lib/plugins/worker_structure.js @@ -1,30 +1,6 @@ var _ = require("lodash"); // Because of _.merge var semver = require("semver"); -/** - * PreProcess. - * - * @param {Object[]} parsedFiles - * @param {String[]} filenames - * @returns {Object} - */ -function preProcess(parsedFiles, filenames) -{ - return _preProcess(parsedFiles, filenames, "structure", "defineStructure"); -} // preProcess - -/** - * PostProcess. - * - * @param {Object[]} parsedFiles - * @param {String[]} filenames - * @param {Object[]} preProcessResults - */ -function postProcess(parsedFiles, filenames, preProcessResults) -{ - _postProcess(parsedFiles, filenames, preProcessResults, "structure", "defineStructure"); -} // postProcess - /** * PreProcess. * @@ -34,8 +10,10 @@ function postProcess(parsedFiles, filenames, preProcessResults) * @param {String} defineStructureName * @returns {Object} */ -function _preProcess(parsedFiles, filenames, structureName, defineStructureName) +function preProcess(parsedFiles, filenames, structureName, defineStructureName) { + structureName = structureName || "structure"; + defineStructureName = defineStructureName || "defineStructure"; var result = {}; for(var fileIndex = 0; fileIndex < parsedFiles.length; fileIndex += 1) { @@ -53,13 +31,14 @@ function _preProcess(parsedFiles, filenames, structureName, defineStructureName) version = block.version; } - if( ! result[name]) result[name] = {}; - result[name][version] = block.local; + if( ! result[defineStructureName]) result[defineStructureName] = {}; + if( ! result[defineStructureName][name]) result[defineStructureName][name] = {}; + result[defineStructureName][name][version] = block.local; } } // for blockIndex } // for fileIndex return result; -} // _preProcess +} // preProcess /** * PostProcess. @@ -70,8 +49,10 @@ function _preProcess(parsedFiles, filenames, structureName, defineStructureName) * @param {String} structureName * @param {String} defineStructureName */ -function _postProcess(parsedFiles, filenames, preProcessResults, structureName, defineStructureName) +function postProcess(parsedFiles, filenames, preProcessResults, structureName, defineStructureName) { + structureName = structureName || "structure"; + defineStructureName = defineStructureName || "defineStructure"; for(var fileIndex = 0; fileIndex < parsedFiles.length; fileIndex += 1) { var parsedFile = parsedFiles[fileIndex]; @@ -88,14 +69,14 @@ function _postProcess(parsedFiles, filenames, preProcessResults, structureName, version = block.version; } - if(preProcessResults[name]) + if(preProcessResults[defineStructureName][name]) { var matchedData = {}; var matchedVersion = version; - if(preProcessResults[name][version]) + if(preProcessResults[defineStructureName][name][version]) { // Exact Version - matchedData = preProcessResults[name][version]; + matchedData = preProcessResults[defineStructureName][name][version]; } else { @@ -103,7 +84,7 @@ function _postProcess(parsedFiles, filenames, preProcessResults, structureName, var foundIndex = -1; var lastVersion = "0.0.0"; - var versionKeys = Object.keys(preProcessResults[name]); + var versionKeys = Object.keys(preProcessResults[defineStructureName][name]); for(var versionIndex = 0; versionIndex < versionKeys.length; versionIndex += 1) { var currentVersion = versionKeys[versionIndex]; @@ -122,7 +103,7 @@ function _postProcess(parsedFiles, filenames, preProcessResults, structureName, ); } var versionName = versionKeys[foundIndex]; - matchedData = preProcessResults[name][versionName]; + matchedData = preProcessResults[defineStructureName][name][versionName]; } // Copy matched elements into parsed block @@ -140,7 +121,7 @@ function _postProcess(parsedFiles, filenames, preProcessResults, structureName, } } // for blockIndex } // for fileIndex -} // _postProcess +} // postProcess /** * Recursive Merge of Objects with Arrays. @@ -166,7 +147,5 @@ function _recursiveMerge(block, matchedData) */ module.exports = { preProcess: preProcess, - postProcess: postProcess, - _preProcess: _preProcess, - _postProcess: _postProcess + postProcess: postProcess }; \ No newline at end of file diff --git a/lib/plugins/worker_success_structure.js b/lib/plugins/worker_success_structure.js index afaffae4..b8db13b9 100644 --- a/lib/plugins/worker_success_structure.js +++ b/lib/plugins/worker_success_structure.js @@ -9,7 +9,7 @@ var apiWorker = require("./worker_structure.js"); */ function preProcess(parsedFiles, filenames) { - return apiWorker._preProcess(parsedFiles, filenames, "successStructure", "defineSuccessStructure"); + return apiWorker.preProcess(parsedFiles, filenames, "successStructure", "defineSuccessStructure"); } // preProcess /** @@ -21,7 +21,7 @@ function preProcess(parsedFiles, filenames) */ function postProcess(parsedFiles, filenames, preProcessResults) { - apiWorker._postProcess(parsedFiles, filenames, preProcessResults, "successStructure", "defineSuccessStructure"); + apiWorker.postProcess(parsedFiles, filenames, preProcessResults, "successStructure", "defineSuccessStructure"); } // postProcess /** diff --git a/lib/plugins/worker_success_title.js b/lib/plugins/worker_success_title.js new file mode 100644 index 00000000..cc70f473 --- /dev/null +++ b/lib/plugins/worker_success_title.js @@ -0,0 +1,33 @@ +var apiWorker = require("./worker_param_title.js"); + +/** + * PreProcess. + * + * @param {Object[]} parsedFiles + * @param {String[]} filenames + * @returns {Object} + */ +function preProcess(parsedFiles, filenames) +{ + return apiWorker.preProcess(parsedFiles, filenames, "successTitle"); +} // preProcess + +/** + * PostProcess. + * + * @param {Object[]} parsedFiles + * @param {String[]} filenames + * @param {Object[]} preProcessResults + */ +function postProcess(parsedFiles, filenames, preProcessResults) +{ + apiWorker.postProcess(parsedFiles, filenames, preProcessResults, "success", "successTitle"); +} // postProcess + +/** + * Exports. + */ +module.exports = { + preProcess: preProcess, + postProcess: postProcess, +}; \ No newline at end of file diff --git a/package.json b/package.json index 61e3b282..8c48621a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "apidoc", - "version": "0.1.11", + "version": "0.2.0", "description": "RESTful web API Documentation Generator", "author": "Peter Rottmann ", "license": "MIT", diff --git a/template/css/style.css b/template/css/style.css index 92acfb57..9b6d266a 100644 --- a/template/css/style.css +++ b/template/css/style.css @@ -315,6 +315,17 @@ pre.del { text-decoration: line-through; } +table.ins th, +table.ins td { + background-color: #60d060; +} + +table.del th, +table.del td { + background-color: #f05050; + text-decoration: line-through; +} + tr.ins td { background-color: #60d060; } diff --git a/template/handlebars_helper.js b/template/handlebars_helper.js index 16484a59..0d950966 100644 --- a/template/handlebars_helper.js +++ b/template/handlebars_helper.js @@ -3,37 +3,6 @@ define([ "handlebars", "diffMatchPatch" ], function(locale, Handlebars, DiffMatchPatch) { - var diffMatchPatch = new DiffMatchPatch(); - - /** - * Overwrite Colors - */ - DiffMatchPatch.prototype.diff_prettyHtml = function(diffs) { - var html = []; - var pattern_amp = /&/g; - var pattern_lt = //g; - var pattern_para = /\n/g; - for (var x = 0; x < diffs.length; x++) { - var op = diffs[x][0]; // Operation (insert, delete, equal) - var data = diffs[x][1]; // Text of change. - var text = data.replace(pattern_amp, '&').replace(pattern_lt, '<') - .replace(pattern_gt, '>').replace(pattern_para, '¶
'); - switch (op) { - case DIFF_INSERT: - html[x] = '' + text + ''; - break; - case DIFF_DELETE: - html[x] = '' + text + ''; - break; - case DIFF_EQUAL: - html[x] = '' + text + ''; - break; - } - } - return html.join(''); - }; - /** * Return localized Text. * @param string text @@ -64,20 +33,6 @@ define([ return ""; }); - /** - * - */ - Handlebars.registerHelper("each_compare_field", function(source, compare, options) { - return _handlebarsEachCompared("field", source, compare, options); - }); - - /** - * - */ - Handlebars.registerHelper("each_compare_title", function(source, compare, options) { - return _handlebarsEachCompared("title", source, compare, options); - }); - /** * */ @@ -93,25 +48,6 @@ define([ return options.inverse(this); }); - /** - * - */ - Handlebars.registerHelper("showDiff", function(source, compare, options) { - var ds = ""; - if(source === compare) ds = source; - else - { - if( ! source) return compare; - if( ! compare) return source; - var d = diffMatchPatch.diff_main(compare, source); - diffMatchPatch.diff_cleanupSemantic(d); - ds = diffMatchPatch.diff_prettyHtml(d); - ds = ds.replace(/¶/gm, ""); - } - if(options === "nl2br") ds = _handlebarsNewlineToBreak(ds); - return ds; - }); - /** * */ @@ -148,6 +84,69 @@ define([ return (text + "").replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, "$1" + "
" + "$2"); } // _handlebarsNewlineToBreak + /** + * + */ + Handlebars.registerHelper("each_compare_keys", function(source, compare, options) { + var newSource = []; + if(source) + { + var sourceFields = Object.keys(source); + sourceFields.forEach(function(name) { + var values = {}; + values["value"] = source[name]; + values["key"] = name; + newSource.push(values); + }); + } + + var newCompare = []; + if(compare) + { + var compareFields = Object.keys(compare); + compareFields.forEach(function(name) { + var values = {}; + values["value"] = compare[name]; + values["key"] = name; + newCompare.push(values); + }); + } + return _handlebarsEachCompared("key", newSource, newCompare, options); + }); + + /** + * + */ + Handlebars.registerHelper("each_compare_field", function(source, compare, options) { + return _handlebarsEachCompared("field", source, compare, options); + }); + + /** + * + */ + Handlebars.registerHelper("each_compare_title", function(source, compare, options) { + return _handlebarsEachCompared("title", source, compare, options); + }); + + /** + * + */ + Handlebars.registerHelper("showDiff", function(source, compare, options) { + var ds = ""; + if(source === compare) ds = source; + else + { + if( ! source) return compare; + if( ! compare) return source; + var d = diffMatchPatch.diff_main(compare, source); + diffMatchPatch.diff_cleanupSemantic(d); + ds = diffMatchPatch.diff_prettyHtml(d); + ds = ds.replace(/¶/gm, ""); + } + if(options === "nl2br") ds = _handlebarsNewlineToBreak(ds); + return ds; + }); + /** * */ @@ -216,5 +215,36 @@ define([ return ret; } // _handlebarsEachCompared + var diffMatchPatch = new DiffMatchPatch(); + + /** + * Overwrite Colors + */ + DiffMatchPatch.prototype.diff_prettyHtml = function(diffs) { + var html = []; + var pattern_amp = /&/g; + var pattern_lt = //g; + var pattern_para = /\n/g; + for (var x = 0; x < diffs.length; x++) { + var op = diffs[x][0]; // Operation (insert, delete, equal) + var data = diffs[x][1]; // Text of change. + var text = data.replace(pattern_amp, '&').replace(pattern_lt, '<') + .replace(pattern_gt, '>').replace(pattern_para, '¶
'); + switch (op) { + case DIFF_INSERT: + html[x] = '' + text + ''; + break; + case DIFF_DELETE: + html[x] = '' + text + ''; + break; + case DIFF_EQUAL: + html[x] = '' + text + ''; + break; + } + } + return html.join(''); + }; + return Handlebars; }); \ No newline at end of file diff --git a/template/index.html b/template/index.html index 74784ecd..54a5329f 100644 --- a/template/index.html +++ b/template/index.html @@ -120,42 +120,43 @@

{{underscoreToSpace article.group}} - {{article.title}}

{{{content}}}
{{/each}} - {{subTemplate "article-param-block" params=article.parameter _title="Parameter" _hasType=_hasTypeInParameterFields}} - {{subTemplate "article-param-block" params=article.success _title="Success (200)" _hasType=_hasTypeInSuccessFields}} - {{subTemplate "article-param-block" params=article.info _title="Info" _hasType=_hasTypeInInfoFields}} - {{subTemplate "article-param-block" params=article.error _title="Error (4xx)" _col1="Name" _hasType=_hasTypeInErrorFields}} + {{subTemplate "article-param-block" params=article.parameter _hasType=_hasTypeInParameterFields}} + {{subTemplate "article-param-block" params=article.success _hasType=_hasTypeInSuccessFields}} + {{subTemplate "article-param-block" params=article.info _hasType=_hasTypeInInfoFields}} + {{subTemplate "article-param-block" params=article.error _col1="Name" _hasType=_hasTypeInErrorFields}} @@ -216,10 +217,10 @@

{{underscoreToSpace article.group}} - {{{showDiff article.title compare.titl {{/each_compare_title}} - {{subTemplate "article-compare-param-block" source=article.parameter compare=compare.parameter _title="Parameter" _hasType=_hasTypeInParameterFields}} - {{subTemplate "article-compare-param-block" source=article.success compare=compare.success _title="Success (200)" _hasType=_hasTypeInSuccessFields}} - {{subTemplate "article-compare-param-block" source=article.info compare=compare.info _title="Info" _hasType=_hasTypeInInfoFields}} - {{subTemplate "article-compare-param-block" source=article.error compare=compare.error _title="Error (4xx)" _col1="Name" _hasType=_hasTypeInErrorFields}} + {{subTemplate "article-compare-param-block" source=article.parameter compare=compare.parameter _hasType=_hasTypeInParameterFields}} + {{subTemplate "article-compare-param-block" source=article.success compare=compare.success _hasType=_hasTypeInSuccessFields}} + {{subTemplate "article-compare-param-block" source=article.info compare=compare.info _hasType=_hasTypeInInfoFields}} + {{subTemplate "article-compare-param-block" source=article.error compare=compare.error _col1="Name" _hasType=_hasTypeInErrorFields}} @@ -304,20 +305,74 @@

{{underscoreToSpace article.group}} - {{{showDiff article.title compare.titl + +
diff --git a/template/locales/de.js b/template/locales/de.js index fc941e18..b97f6ccb 100644 --- a/template/locales/de.js +++ b/template/locales/de.js @@ -3,8 +3,8 @@ define({ "Compare all with predecessor": "Vergleiche alle mit ihren Vorgängern", "compare changes to:" : "vergleiche Änderungen mit:", "compared to" : "verglichen mit", + "Default value:" : "Standardwert:", "Description" : "Beschreibung", - "Error (4xx)" : "Error (4xx)", "Field" : "Feld", "General" : "Allgemein", "Generated with" : "Erstellt mit", @@ -14,7 +14,6 @@ define({ "Parameter" : "Parameter", "Permission:" : "Berechtigung:", "show up to version:" : "zeige bis zur Version:", - "Success (200)" : "Success (200)", "Type" : "Typ" } }); \ No newline at end of file diff --git a/template/main.js b/template/main.js index 653a189c..bcb54105 100644 --- a/template/main.js +++ b/template/main.js @@ -78,11 +78,12 @@ require([ // Titel der ersten Einträge von group[].name[] ermitteln (name hat Versionsliste) var titles = {}; $.each(groupEntries, function(index, entries) { - var title = entries[0].title; - if (title) { - title.toLowerCase().replace(/[äöüß]/g, function($0) { return umlauts[$0]; }); - titles[title + " #~#" + index] = 1; - } + var title = entries[0].title; + if(title) + { + title.toLowerCase().replace(/[äöüß]/g, function($0) { return umlauts[$0]; }); + titles[title + " #~#" + index] = 1; + } }); // each // Sortieren var values = Object.keys(titles); @@ -239,12 +240,12 @@ require([ versions: articleVersions[entry.group][entry.name] }; } - - if(entry.parameter && entry.parameter.fields) fields._hasTypeInParameterFields = _.any(entry.parameter.fields, function(item) { return item.type; }); - if(entry.error && entry.error.fields) fields._hasTypeInErrorFields = _.any(entry.error.fields, function(item) { return item.type; }); - if(entry.success && entry.success.fields) fields._hasTypeInSuccessFields = _.any(entry.success.fields, function(item) { return item.type; }); - if(entry.info && entry.info.fields) fields._hasTypeInInfoFields = _.any(entry.info.fields, function(item) { return item.type; }); - + + if(entry.parameter && entry.parameter.fields) fields._hasTypeInParameterFields = _hasTypeInFields(entry.parameter.fields); + if(entry.error && entry.error.fields) fields._hasTypeInErrorFields = _hasTypeInFields(entry.error.fields); + if(entry.success && entry.success.fields) fields._hasTypeInSuccessFields = _hasTypeInFields(entry.success.fields); + if(entry.info && entry.info.fields) fields._hasTypeInInfoFields = _hasTypeInFields(entry.info.fields); + articles.push({ article: templateArticle(fields), group: entry.group, @@ -283,6 +284,25 @@ require([ $('html,body').animate({ scrollTop: parseInt($(id).offset().top) - 18 }, 0); } + /** + * Check if Parameter (sub) List has a type Field. + * Example: @apaSuccess varname1 No type. + * @apaSuccess {String} varname2 With type. + * + * @param {Object} fields + */ + function _hasTypeInFields(fields) + { + hasField = false; + $.each(fields, function(name) { + if(_.any(fields[name], function(item) { return item.type; }) ) + { + hasField = true; + } + }); + return hasField; + } // _hasTypeInFields + /** * On Template changes, recall plugins. */ @@ -358,7 +378,7 @@ require([ // On change the Version of an article. $("article .versions li.version a").on("click", changeVersionCompareTo); - + /** * */ @@ -406,14 +426,16 @@ require([ }; var entry = sourceEntry; - if(entry.parameter && entry.parameter.fields) fields._hasTypeInParameterFields = _.any(entry.parameter.fields, function(item) { return item.type; }); - if(entry.error && entry.error.fields) fields._hasTypeInErrorFields = _.any(entry.error.fields, function(item) { return item.type; }); - if(entry.success && entry.success.fields) fields._hasTypeInSuccessFields = _.any(entry.success.fields, function(item) { return item.type; }); + if(entry.parameter && entry.parameter.fields) fields._hasTypeInParameterFields = _hasTypeInFields(entry.parameter.fields); + if(entry.error && entry.error.fields) fields._hasTypeInErrorFields = _hasTypeInFields(entry.error.fields); + if(entry.success && entry.success.fields) fields._hasTypeInSuccessFields = _hasTypeInFields(entry.success.fields); + if(entry.info && entry.info.fields) fields._hasTypeInInfoFields = _hasTypeInFields(entry.info.fields); var entry = compareEntry; - if(fields._hasTypeInParameterFields !== true && entry.parameter && entry.parameter.fields) fields._hasTypeInParameterFields = _.any(entry.parameter.fields, function(item) { return item.type; }); - if(entry.error && entry.error.fields) fields._hasTypeInErrorFields = _.any(entry.error.fields, function(item) { return item.type; }); - if(fields._hasTypeInParameterFields !== true && entry.success && entry.success.fields) fields._hasTypeInSuccessFields = _.any(entry.success.fields, function(item) { return item.type; }); + if(fields._hasTypeInParameterFields !== true && entry.parameter && entry.parameter.fields) fields._hasTypeInParameterFields = _hasTypeInFields(entry.parameter.fields); + if(fields._hasTypeInErrorFields !== true && entry.error && entry.error.fields) fields._hasTypeInErrorFields = _hasTypeInFields(entry.error.fields); + if(fields._hasTypeInSuccessFields !== true && entry.success && entry.success.fields) fields._hasTypeInSuccessFields = _hasTypeInFields(entry.success.fields); + if(fields._hasTypeInInfoFields !== true && entry.info && entry.info.fields) fields._hasTypeInInfoFields = _hasTypeInFields(entry.info.fields); var content = templateCompareArticle(fields); $root.after(content); @@ -475,9 +497,10 @@ require([ versions: articleVersions[group][name] }; - if(entry.parameter && entry.parameter.fields) fields._hasTypeInParameterFields = _.any(entry.parameter.fields, function(item) { return item.type; }); - if(entry.error && entry.error.fields) fields._hasTypeInErrorFields = _.any(entry.error.fields, function(item) { return item.type; }); - if(entry.success && entry.success.fields) fields._hasTypeInSuccessFields = _.any(entry.success.fields, function(item) { return item.type; }); + if(entry.parameter && entry.parameter.fields) fields._hasTypeInParameterFields = _hasTypeInFields(entry.parameter.fields); + if(entry.error && entry.error.fields) fields._hasTypeInErrorFields = _hasTypeInFields(entry.error.fields); + if(entry.success && entry.success.fields) fields._hasTypeInSuccessFields = _hasTypeInFields(entry.success.fields); + if(entry.info && entry.info.fields) fields._hasTypeInInfoFields = _hasTypeInFields(entry.info.fields); return templateArticle(fields); } // renderArticle diff --git a/template/vendor/handlebars.min.js b/template/vendor/handlebars.min.js index afd91781..1915ee69 100644 --- a/template/vendor/handlebars.min.js +++ b/template/vendor/handlebars.min.js @@ -1,96 +1,24 @@ -this.Handlebars={}; -(function(Handlebars){Handlebars.VERSION="1.0.0-rc.3";Handlebars.COMPILER_REVISION=2;Handlebars.REVISION_CHANGES={1:"<= 1.0.rc.2",2:">= 1.0.0-rc.3"};Handlebars.helpers={};Handlebars.partials={};Handlebars.registerHelper=function(name,fn,inverse){if(inverse)fn.not=inverse;this.helpers[name]=fn};Handlebars.registerPartial=function(name,str){this.partials[name]=str};Handlebars.registerHelper("helperMissing",function(arg){if(arguments.length===2)return undefined;else throw new Error("Could not find property '"+arg+ -"'");});var toString=Object.prototype.toString,functionType="[object Function]";Handlebars.registerHelper("blockHelperMissing",function(context,options){var inverse=options.inverse||function(){},fn=options.fn;var ret="";var type=toString.call(context);if(type===functionType)context=context.call(this);if(context===true)return fn(this);else if(context===false||context==null)return inverse(this);else if(type==="[object Array]")if(context.length>0)return Handlebars.helpers.each(context,options);else return inverse(this); -else return fn(context)});Handlebars.K=function(){};Handlebars.createFrame=Object.create||function(object){Handlebars.K.prototype=object;var obj=new Handlebars.K;Handlebars.K.prototype=null;return obj};Handlebars.logger={DEBUG:0,INFO:1,WARN:2,ERROR:3,level:3,methodMap:{"0":"debug",1:"info",2:"warn",3:"error"},log:function(level,obj){if(Handlebars.logger.level<=level){var method=Handlebars.logger.methodMap[level];if(typeof console!=="undefined"&&console[method])console[method].call(console,obj)}}}; -Handlebars.log=function(level,obj){Handlebars.logger.log(level,obj)};Handlebars.registerHelper("each",function(context,options){var fn=options.fn,inverse=options.inverse;var i=0,ret="",data;if(options.data)data=Handlebars.createFrame(options.data);if(context&&typeof context==="object")if(context instanceof Array)for(var j=context.length;i2)expected.push("'"+this.terminals_[p]+"'");if(this.lexer.showPosition)errStr="Parse error on line "+(yylineno+1)+":\n"+this.lexer.showPosition()+"\nExpecting "+ -expected.join(", ")+", got '"+(this.terminals_[symbol]||symbol)+"'";else errStr="Parse error on line "+(yylineno+1)+": Unexpected "+(symbol==1?"end of input":"'"+(this.terminals_[symbol]||symbol)+"'");this.parseError(errStr,{text:this.lexer.match,token:this.terminals_[symbol]||symbol,line:this.lexer.yylineno,loc:yyloc,expected:expected})}}if(action[0]instanceof Array&&action.length>1)throw new Error("Parse Error: multiple actions possible at state: "+state+", token: "+symbol);switch(action[0]){case 1:stack.push(symbol); -vstack.push(this.lexer.yytext);lstack.push(this.lexer.yylloc);stack.push(action[1]);symbol=null;if(!preErrorSymbol){yyleng=this.lexer.yyleng;yytext=this.lexer.yytext;yylineno=this.lexer.yylineno;yyloc=this.lexer.yylloc;if(recovering>0)recovering--}else{symbol=preErrorSymbol;preErrorSymbol=null}break;case 2:len=this.productions_[action[1]][1];yyval.$=vstack[vstack.length-len];yyval._$={first_line:lstack[lstack.length-(len||1)].first_line,last_line:lstack[lstack.length-1].last_line,first_column:lstack[lstack.length- -(len||1)].first_column,last_column:lstack[lstack.length-1].last_column};if(ranges)yyval._$.range=[lstack[lstack.length-(len||1)].range[0],lstack[lstack.length-1].range[1]];r=this.performAction.call(yyval,yytext,yyleng,yylineno,this.yy,action[1],vstack,lstack);if(typeof r!=="undefined")return r;if(len){stack=stack.slice(0,-1*len*2);vstack=vstack.slice(0,-1*len);lstack=lstack.slice(0,-1*len)}stack.push(this.productions_[action[1]][0]);vstack.push(yyval.$);lstack.push(yyval._$);newState=table[stack[stack.length- -2]][stack[stack.length-1]];stack.push(newState);break;case 3:return true}}return true}};var lexer=function(){var lexer={EOF:1,parseError:function parseError(str,hash){if(this.yy.parser)this.yy.parser.parseError(str,hash);else throw new Error(str);},setInput:function(input){this._input=input;this._more=this._less=this.done=false;this.yylineno=this.yyleng=0;this.yytext=this.matched=this.match="";this.conditionStack=["INITIAL"];this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0};if(this.options.ranges)this.yylloc.range= -[0,0];this.offset=0;return this},input:function(){var ch=this._input[0];this.yytext+=ch;this.yyleng++;this.offset++;this.match+=ch;this.matched+=ch;var lines=ch.match(/(?:\r\n?|\n).*/g);if(lines){this.yylineno++;this.yylloc.last_line++}else this.yylloc.last_column++;if(this.options.ranges)this.yylloc.range[1]++;this._input=this._input.slice(1);return ch},unput:function(ch){var len=ch.length;var lines=ch.split(/(?:\r\n?|\n)/g);this._input=ch+this._input;this.yytext=this.yytext.substr(0,this.yytext.length- -len-1);this.offset-=len;var oldLines=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1);this.matched=this.matched.substr(0,this.matched.length-1);if(lines.length-1)this.yylineno-=lines.length-1;var r=this.yylloc.range;this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:lines?(lines.length===oldLines.length?this.yylloc.first_column:0)+oldLines[oldLines.length-lines.length].length-lines[0].length: -this.yylloc.first_column-len};if(this.options.ranges)this.yylloc.range=[r[0],r[0]+this.yyleng-len];return this},more:function(){this._more=true;return this},less:function(n){this.unput(this.match.slice(n))},pastInput:function(){var past=this.matched.substr(0,this.matched.length-this.match.length);return(past.length>20?"...":"")+past.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var next=this.match;if(next.length<20)next+=this._input.substr(0,20-next.length);return(next.substr(0,20)+(next.length> -20?"...":"")).replace(/\n/g,"")},showPosition:function(){var pre=this.pastInput();var c=(new Array(pre.length+1)).join("-");return pre+this.upcomingInput()+"\n"+c+"^"},next:function(){if(this.done)return this.EOF;if(!this._input)this.done=true;var token,match,tempMatch,index,col,lines;if(!this._more){this.yytext="";this.match=""}var rules=this._currentRules();for(var i=0;imatch[0].length)){match= -tempMatch;index=i;if(!this.options.flex)break}}if(match){lines=match[0].match(/(?:\r\n?|\n).*/g);if(lines)this.yylineno+=lines.length;this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:lines?lines[lines.length-1].length-lines[lines.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+match[0].length};this.yytext+=match[0];this.match+=match[0];this.matches=match;this.yyleng=this.yytext.length;if(this.options.ranges)this.yylloc.range= -[this.offset,this.offset+=this.yyleng];this._more=false;this._input=this._input.slice(match[0].length);this.matched+=match[0];token=this.performAction.call(this,this.yy,this,rules[index],this.conditionStack[this.conditionStack.length-1]);if(this.done&&this._input)this.done=false;if(token)return token;else return}if(this._input==="")return this.EOF;else return this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}, -lex:function lex(){var r=this.next();if(typeof r!=="undefined")return r;else return this.lex()},begin:function begin(condition){this.conditionStack.push(condition)},popState:function popState(){return this.conditionStack.pop()},_currentRules:function _currentRules(){return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules},topState:function(){return this.conditionStack[this.conditionStack.length-2]},pushState:function begin(condition){this.begin(condition)}};lexer.options={}; -lexer.performAction=function anonymous(yy,yy_,$avoiding_name_collisions,YY_START){var YYSTATE=YY_START;switch($avoiding_name_collisions){case 0:if(yy_.yytext.slice(-1)!=="\\")this.begin("mu");if(yy_.yytext.slice(-1)==="\\")yy_.yytext=yy_.yytext.substr(0,yy_.yyleng-1),this.begin("emu");if(yy_.yytext)return 14;break;case 1:return 14;break;case 2:if(yy_.yytext.slice(-1)!=="\\")this.popState();if(yy_.yytext.slice(-1)==="\\")yy_.yytext=yy_.yytext.substr(0,yy_.yyleng-1);return 14;break;case 3:yy_.yytext= -yy_.yytext.substr(0,yy_.yyleng-4);this.popState();return 15;break;case 4:this.begin("par");return 24;break;case 5:return 16;break;case 6:return 20;break;case 7:return 19;break;case 8:return 19;break;case 9:return 23;break;case 10:return 23;break;case 11:this.popState();this.begin("com");break;case 12:yy_.yytext=yy_.yytext.substr(3,yy_.yyleng-5);this.popState();return 15;break;case 13:return 22;break;case 14:return 36;break;case 15:return 35;break;case 16:return 35;break;case 17:return 39;break;case 18:break; -case 19:this.popState();return 18;break;case 20:this.popState();return 18;break;case 21:yy_.yytext=yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\"/g,'"');return 30;break;case 22:yy_.yytext=yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\'/g,"'");return 30;break;case 23:yy_.yytext=yy_.yytext.substr(1);return 28;break;case 24:return 32;break;case 25:return 32;break;case 26:return 31;break;case 27:return 35;break;case 28:yy_.yytext=yy_.yytext.substr(1,yy_.yyleng-2);return 35;break;case 29:return"INVALID"; -break;case 30:break;case 31:this.popState();return 37;break;case 32:return 5;break}};lexer.rules=[/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\{\{>)/,/^(?:\{\{#)/,/^(?:\{\{\/)/,/^(?:\{\{\^)/,/^(?:\{\{\s*else\b)/,/^(?:\{\{\{)/,/^(?:\{\{&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{)/,/^(?:=)/,/^(?:\.(?=[} ]))/,/^(?:\.\.)/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}\}\})/,/^(?:\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@[a-zA-Z]+)/, -/^(?:true(?=[}\s]))/,/^(?:false(?=[}\s]))/,/^(?:[0-9]+(?=[}\s]))/,/^(?:[a-zA-Z0-9_$-]+(?=[=}\s\/.]))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:\s+)/,/^(?:[a-zA-Z0-9_$-/]+)/,/^(?:$)/];lexer.conditions={"mu":{"rules":[4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,32],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"com":{"rules":[3],"inclusive":false},"par":{"rules":[30,31],"inclusive":false},"INITIAL":{"rules":[0,1,32],"inclusive":true}};return lexer}();parser.lexer=lexer; -function Parser(){this.yy={}}Parser.prototype=parser;parser.Parser=Parser;return new Parser}();Handlebars.Parser=handlebars;Handlebars.parse=function(input){if(input.constructor===Handlebars.AST.ProgramNode)return input;Handlebars.Parser.yy=Handlebars.AST;return Handlebars.Parser.parse(input)};Handlebars.print=function(ast){return(new Handlebars.PrintVisitor).accept(ast)}; -(function(){Handlebars.AST={};Handlebars.AST.ProgramNode=function(statements,inverse){this.type="program";this.statements=statements;if(inverse)this.inverse=new Handlebars.AST.ProgramNode(inverse)};Handlebars.AST.MustacheNode=function(rawParams,hash,unescaped){this.type="mustache";this.escaped=!unescaped;this.hash=hash;var id=this.id=rawParams[0];var params=this.params=rawParams.slice(1);var eligibleHelper=this.eligibleHelper=id.isSimple;this.isHelper=eligibleHelper&&(params.length||hash)};Handlebars.AST.PartialNode= -function(partialName,context){this.type="partial";this.partialName=partialName;this.context=context};var verifyMatch=function(open,close){if(open.original!==close.original)throw new Handlebars.Exception(open.original+" doesn't match "+close.original);};Handlebars.AST.BlockNode=function(mustache,program,inverse,close){verifyMatch(mustache.id,close);this.type="block";this.mustache=mustache;this.program=program;this.inverse=inverse;if(this.inverse&&!this.program)this.isInverse=true};Handlebars.AST.ContentNode= -function(string){this.type="content";this.string=string};Handlebars.AST.HashNode=function(pairs){this.type="hash";this.pairs=pairs};Handlebars.AST.IdNode=function(parts){this.type="ID";this.original=parts.join(".");var dig=[],depth=0;for(var i=0,l=parts.length;i0)throw new Handlebars.Exception("Invalid path: "+this.original);else if(part==="..")depth++;else this.isScoped=true;else dig.push(part)}this.parts=dig;this.string= -dig.join(".");this.depth=depth;this.isSimple=parts.length===1&&!this.isScoped&&depth===0;this.stringModeValue=this.string};Handlebars.AST.PartialNameNode=function(name){this.type="PARTIAL_NAME";this.name=name};Handlebars.AST.DataNode=function(id){this.type="DATA";this.id=id};Handlebars.AST.StringNode=function(string){this.type="STRING";this.string=string;this.stringModeValue=string};Handlebars.AST.IntegerNode=function(integer){this.type="INTEGER";this.integer=integer;this.stringModeValue=Number(integer)}; -Handlebars.AST.BooleanNode=function(bool){this.type="BOOLEAN";this.bool=bool;this.stringModeValue=bool==="true"};Handlebars.AST.CommentNode=function(comment){this.type="comment";this.comment=comment}})();var errorProps=["description","fileName","lineNumber","message","name","number","stack"];Handlebars.Exception=function(message){var tmp=Error.prototype.constructor.apply(this,arguments);for(var idx=0;idx":">",'"':""","'":"'","`":"`"};var badChars=/[&<>"'`]/g;var possible=/[&<>"'`]/;var escapeChar=function(chr){return escape[chr]||"&"};Handlebars.Utils={escapeExpression:function(string){if(string instanceof Handlebars.SafeString)return string.toString();else if(string==null||string===false)return"";if(!possible.test(string))return string;return string.replace(badChars,escapeChar)},isEmpty:function(value){if(!value&&value!==0)return true; -else if(Object.prototype.toString.call(value)==="[object Array]"&&value.length===0)return true;else return false}}})();Handlebars.Compiler=function(){};Handlebars.JavaScriptCompiler=function(){}; -(function(Compiler,JavaScriptCompiler){Compiler.prototype={compiler:Compiler,disassemble:function(){var opcodes=this.opcodes,opcode,out=[],params,param;for(var i=0,l=opcodes.length;i0)this.source[1]=this.source[1]+", "+locals.join(", ");if(!this.isChild)for(var alias in this.context.aliases)this.source[1]=this.source[1]+", "+alias+"="+this.context.aliases[alias];if(this.source[1])this.source[1]="var "+this.source[1].substring(2)+";";if(!this.isChild)this.source[1]+="\n"+this.context.programs.join("\n")+"\n";if(!this.environment.isSimple)this.source.push("return buffer;"); -var params=this.isChild?["depth0","data"]:["Handlebars","depth0","helpers","partials","data"];for(var i=0,l=this.environment.depths.list.length;ithis.stackVars.length)this.stackVars.push("stack"+this.stackSlot); -return this.topStackName()},topStackName:function(){return"stack"+this.stackSlot},flushInline:function(){var inlineStack=this.inlineStack;if(inlineStack.length){this.inlineStack=[];for(var i=0,len=inlineStack.length;i= 1.0.0-rc.4"};d.helpers={};d.partials={};var n=Object.prototype.toString,b="[object Function]",h="[object Object]";d.registerHelper=function(l,u,i){if(n.call(l)===h){if(i||u){throw new d.Exception("Arg not supported with multiple helpers")}d.Utils.extend(this.helpers,l)}else{if(i){u.not=i}this.helpers[l]=u}};d.registerPartial=function(i,l){if(n.call(i)===h){d.Utils.extend(this.partials,i)}else{this.partials[i]=l}};d.registerHelper("helperMissing",function(i){if(arguments.length===2){return c}else{throw new Error("Could not find property '"+i+"'")}});d.registerHelper("blockHelperMissing",function(u,l){var i=l.inverse||function(){},w=l.fn;var v=n.call(u);if(v===b){u=u.call(this)}if(u===true){return w(this)}else{if(u===false||u==null){return i(this)}else{if(v==="[object Array]"){if(u.length>0){return d.helpers.each(u,l)}else{return i(this)}}else{return w(u)}}}});d.K=function(){};d.createFrame=Object.create||function(i){d.K.prototype=i;var l=new d.K();d.K.prototype=null;return l};d.logger={DEBUG:0,INFO:1,WARN:2,ERROR:3,level:3,methodMap:{0:"debug",1:"info",2:"warn",3:"error"},log:function(u,i){if(d.logger.level<=u){var l=d.logger.methodMap[u];if(typeof console!=="undefined"&&console[l]){console[l].call(console,i)}}}};d.log=function(l,i){d.logger.log(l,i)};d.registerHelper("each",function(l,B){var z=B.fn,v=B.inverse;var x=0,y="",w;if(B.data){w=d.createFrame(B.data)}if(l&&typeof l==="object"){if(l instanceof Array){for(var u=l.length;x2){G.push("'"+this.terminals_[Q]+"'")}}if(this.lexer.showPosition){S="Parse error on line "+(J+1)+":\n"+this.lexer.showPosition()+"\nExpecting "+G.join(", ")+", got '"+(this.terminals_[V]||V)+"'"}else{S="Parse error on line "+(J+1)+": Unexpected "+(V==1?"end of input":"'"+(this.terminals_[V]||V)+"'")}this.parseError(S,{text:this.lexer.match,token:this.terminals_[V]||V,line:this.lexer.yylineno,loc:B,expected:G})}}if(U[0] instanceof Array&&U.length>1){throw new Error("Parse Error: multiple actions possible at state: "+E+", token: "+V)}switch(U[0]){case 1:F.push(V);Y.push(this.lexer.yytext);K.push(this.lexer.yylloc);F.push(U[1]);V=null;if(!R){W=this.lexer.yyleng;A=this.lexer.yytext;J=this.lexer.yylineno;B=this.lexer.yylloc;if(C>0){C--}}else{V=R;R=null}break;case 2:X=this.productions_[U[1]][1];T.$=Y[Y.length-X];T._$={first_line:K[K.length-(X||1)].first_line,last_line:K[K.length-1].last_line,first_column:K[K.length-(X||1)].first_column,last_column:K[K.length-1].last_column};if(D){T._$.range=[K[K.length-(X||1)].range[0],K[K.length-1].range[1]]}L=this.performAction.call(T,A,W,J,this.yy,U[1],Y,K);if(typeof L!=="undefined"){return L}if(X){F=F.slice(0,-1*X*2);Y=Y.slice(0,-1*X);K=K.slice(0,-1*X)}F.push(this.productions_[U[1]][0]);Y.push(T.$);K.push(T._$);z=Z[F[F.length-2]][F[F.length-1]];F.push(z);break;case 3:return true}}return true}};var i=(function(){var C=({EOF:1,parseError:function E(H,G){if(this.yy.parser){this.yy.parser.parseError(H,G)}else{throw new Error(H)}},setInput:function(G){this._input=G;this._more=this._less=this.done=false;this.yylineno=this.yyleng=0;this.yytext=this.matched=this.match="";this.conditionStack=["INITIAL"];this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0};if(this.options.ranges){this.yylloc.range=[0,0]}this.offset=0;return this},input:function(){var H=this._input[0];this.yytext+=H;this.yyleng++;this.offset++;this.match+=H;this.matched+=H;var G=H.match(/(?:\r\n?|\n).*/g);if(G){this.yylineno++;this.yylloc.last_line++}else{this.yylloc.last_column++}if(this.options.ranges){this.yylloc.range[1]++}this._input=this._input.slice(1);return H},unput:function(I){var G=I.length;var H=I.split(/(?:\r\n?|\n)/g);this._input=I+this._input;this.yytext=this.yytext.substr(0,this.yytext.length-G-1);this.offset-=G;var K=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1);this.matched=this.matched.substr(0,this.matched.length-1);if(H.length-1){this.yylineno-=H.length-1}var J=this.yylloc.range;this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:H?(H.length===K.length?this.yylloc.first_column:0)+K[K.length-H.length].length-H[0].length:this.yylloc.first_column-G};if(this.options.ranges){this.yylloc.range=[J[0],J[0]+this.yyleng-G]}return this},more:function(){this._more=true;return this},less:function(G){this.unput(this.match.slice(G))},pastInput:function(){var G=this.matched.substr(0,this.matched.length-this.match.length);return(G.length>20?"...":"")+G.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var G=this.match;if(G.length<20){G+=this._input.substr(0,20-G.length)}return(G.substr(0,20)+(G.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var G=this.pastInput();var H=new Array(G.length+1).join("-");return G+this.upcomingInput()+"\n"+H+"^"},next:function(){if(this.done){return this.EOF}if(!this._input){this.done=true}var M,K,H,J,I,G;if(!this._more){this.yytext="";this.match=""}var N=this._currentRules();for(var L=0;LK[0].length)){K=H;J=L;if(!this.options.flex){break}}}if(K){G=K[0].match(/(?:\r\n?|\n).*/g);if(G){this.yylineno+=G.length}this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:G?G[G.length-1].length-G[G.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+K[0].length};this.yytext+=K[0];this.match+=K[0];this.matches=K;this.yyleng=this.yytext.length;if(this.options.ranges){this.yylloc.range=[this.offset,this.offset+=this.yyleng]}this._more=false;this._input=this._input.slice(K[0].length);this.matched+=K[0];M=this.performAction.call(this,this.yy,this,N[J],this.conditionStack[this.conditionStack.length-1]);if(this.done&&this._input){this.done=false}if(M){return M}else{return}}if(this._input===""){return this.EOF}else{return this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})}},lex:function z(){var G=this.next();if(typeof G!=="undefined"){return G}else{return this.lex()}},begin:function A(G){this.conditionStack.push(G)},popState:function F(){return this.conditionStack.pop()},_currentRules:function D(){return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules},topState:function(){return this.conditionStack[this.conditionStack.length-2]},pushState:function A(G){this.begin(G)}});C.options={};C.performAction=function B(K,H,J,G){var I=G;switch(J){case 0:H.yytext="\\";return 14;break;case 1:if(H.yytext.slice(-1)!=="\\"){this.begin("mu")}if(H.yytext.slice(-1)==="\\"){H.yytext=H.yytext.substr(0,H.yyleng-1),this.begin("emu")}if(H.yytext){return 14}break;case 2:return 14;break;case 3:if(H.yytext.slice(-1)!=="\\"){this.popState()}if(H.yytext.slice(-1)==="\\"){H.yytext=H.yytext.substr(0,H.yyleng-1)}return 14;break;case 4:H.yytext=H.yytext.substr(0,H.yyleng-4);this.popState();return 15;break;case 5:this.begin("par");return 24;break;case 6:return 16;break;case 7:return 20;break;case 8:return 19;break;case 9:return 19;break;case 10:return 23;break;case 11:return 23;break;case 12:this.popState();this.begin("com");break;case 13:H.yytext=H.yytext.substr(3,H.yyleng-5);this.popState();return 15;break;case 14:return 22;break;case 15:return 36;break;case 16:return 35;break;case 17:return 35;break;case 18:return 39;break;case 19:break;case 20:this.popState();return 18;break;case 21:this.popState();return 18;break;case 22:H.yytext=H.yytext.substr(1,H.yyleng-2).replace(/\\"/g,'"');return 30;break;case 23:H.yytext=H.yytext.substr(1,H.yyleng-2).replace(/\\'/g,"'");return 30;break;case 24:H.yytext=H.yytext.substr(1);return 28;break;case 25:return 32;break;case 26:return 32;break;case 27:return 31;break;case 28:return 35;break;case 29:H.yytext=H.yytext.substr(1,H.yyleng-2);return 35;break;case 30:return"INVALID";break;case 31:break;case 32:this.popState();return 37;break;case 33:return 5;break}};C.rules=[/^(?:\\\\(?=(\{\{)))/,/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\{\{>)/,/^(?:\{\{#)/,/^(?:\{\{\/)/,/^(?:\{\{\^)/,/^(?:\{\{\s*else\b)/,/^(?:\{\{\{)/,/^(?:\{\{&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{)/,/^(?:=)/,/^(?:\.(?=[}/ ]))/,/^(?:\.\.)/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}\}\})/,/^(?:\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@[a-zA-Z]+)/,/^(?:true(?=[}\s]))/,/^(?:false(?=[}\s]))/,/^(?:-?[0-9]+(?=[}\s]))/,/^(?:[a-zA-Z0-9_$:\-]+(?=[=}\s\/.]))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:\s+)/,/^(?:[a-zA-Z0-9_$\-\/]+)/,/^(?:$)/];C.conditions={mu:{rules:[5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,33],inclusive:false},emu:{rules:[3],inclusive:false},com:{rules:[4],inclusive:false},par:{rules:[31,32],inclusive:false},INITIAL:{rules:[0,1,2,33],inclusive:true}};return C})();y.lexer=i;function w(){this.yy={}}w.prototype=y;y.Parser=w;return new w})();d.Parser=r;d.parse=function(i){if(i.constructor===d.AST.ProgramNode){return i}d.Parser.yy=d.AST;return d.Parser.parse(i)};d.AST={};d.AST.ProgramNode=function(l,i){this.type="program";this.statements=l;if(i){this.inverse=new d.AST.ProgramNode(i)}};d.AST.MustacheNode=function(x,u,l){this.type="mustache";this.escaped=!l;this.hash=u;var w=this.id=x[0];var v=this.params=x.slice(1);var i=this.eligibleHelper=w.isSimple;this.isHelper=i&&(v.length||u)};d.AST.PartialNode=function(i,l){this.type="partial";this.partialName=i;this.context=l};d.AST.BlockNode=function(u,l,i,w){var v=function(x,y){if(x.original!==y.original){throw new d.Exception(x.original+" doesn't match "+y.original)}};v(u.id,w);this.type="block";this.mustache=u;this.program=l;this.inverse=i;if(this.inverse&&!this.program){this.isInverse=true}};d.AST.ContentNode=function(i){this.type="content";this.string=i};d.AST.HashNode=function(i){this.type="hash";this.pairs=i};d.AST.IdNode=function(y){this.type="ID";this.original=y.join(".");var w=[],z=0;for(var x=0,u=y.length;x0){throw new d.Exception("Invalid path: "+this.original)}else{if(v===".."){z++}else{this.isScoped=true}}}else{w.push(v)}}this.parts=w;this.string=w.join(".");this.depth=z;this.isSimple=y.length===1&&!this.isScoped&&z===0;this.stringModeValue=this.string};d.AST.PartialNameNode=function(i){this.type="PARTIAL_NAME";this.name=i};d.AST.DataNode=function(i){this.type="DATA";this.id=i};d.AST.StringNode=function(i){this.type="STRING";this.string=i;this.stringModeValue=i};d.AST.IntegerNode=function(i){this.type="INTEGER";this.integer=i;this.stringModeValue=Number(i)};d.AST.BooleanNode=function(i){this.type="BOOLEAN";this.bool=i;this.stringModeValue=i==="true"};d.AST.CommentNode=function(i){this.type="comment";this.comment=i};var q=["description","fileName","lineNumber","message","name","number","stack"];d.Exception=function(u){var l=Error.prototype.constructor.apply(this,arguments);for(var i=0;i":">",'"':""","'":"'","`":"`"};var e=/[&<>"'`]/g;var p=/[&<>"'`]/;var t=function(i){return k[i]||"&"};d.Utils={extend:function(u,l){for(var i in l){if(l.hasOwnProperty(i)){u[i]=l[i]}}},escapeExpression:function(i){if(i instanceof d.SafeString){return i.toString()}else{if(i==null||i===false){return""}}i=i.toString();if(!p.test(i)){return i}return i.replace(e,t)},isEmpty:function(i){if(!i&&i!==0){return true}else{if(n.call(i)==="[object Array]"&&i.length===0){return true}else{return false}}}};var j=d.Compiler=function(){};var g=d.JavaScriptCompiler=function(){};j.prototype={compiler:j,disassemble:function(){var z=this.opcodes,y,w=[],B,A;for(var x=0,u=z.length;x0){this.source[1]=this.source[1]+", "+w.join(", ")}if(!this.isChild){for(var A in this.context.aliases){this.source[1]=this.source[1]+", "+A+"="+this.context.aliases[A]}}if(this.source[1]){this.source[1]="var "+this.source[1].substring(2)+";"}if(!this.isChild){this.source[1]+="\n"+this.context.programs.join("\n")+"\n"}if(!this.environment.isSimple){this.source.push("return buffer;")}var y=this.isChild?["depth0","data"]:["Handlebars","depth0","helpers","partials","data"];for(var z=0,x=this.environment.depths.list.length;zthis.stackVars.length){this.stackVars.push("stack"+this.stackSlot)}return this.topStackName()},topStackName:function(){return"stack"+this.stackSlot},flushInline:function(){var v=this.inlineStack;if(v.length){this.inlineStack=[];for(var u=0,l=v.length;u{{underscoreToSpace article.group}} - {{article.title}}

{{{content}}}
{{/each}} - {{subTemplate "article-param-block" params=article.parameter _title="Parameter" _hasType=_hasTypeInParameterFields}} - {{subTemplate "article-param-block" params=article.success _title="Success (200)" _hasType=_hasTypeInSuccessFields}} - {{subTemplate "article-param-block" params=article.error _title="Error (4xx)" _col1="Name" _hasType=_hasTypeInErrorFields}} + {{subTemplate "article-param-block" params=article.parameter _hasType=_hasTypeInParameterFields}} + {{subTemplate "article-param-block" params=article.success _hasType=_hasTypeInSuccessFields}} + {{subTemplate "article-param-block" params=article.info _hasType=_hasTypeInInfoFields}} + {{subTemplate "article-param-block" params=article.error _col1="Name" _hasType=_hasTypeInErrorFields}} diff --git a/template_basic/locales/de.js b/template_basic/locales/de.js index fc941e18..b97f6ccb 100644 --- a/template_basic/locales/de.js +++ b/template_basic/locales/de.js @@ -3,8 +3,8 @@ define({ "Compare all with predecessor": "Vergleiche alle mit ihren Vorgängern", "compare changes to:" : "vergleiche Änderungen mit:", "compared to" : "verglichen mit", + "Default value:" : "Standardwert:", "Description" : "Beschreibung", - "Error (4xx)" : "Error (4xx)", "Field" : "Feld", "General" : "Allgemein", "Generated with" : "Erstellt mit", @@ -14,7 +14,6 @@ define({ "Parameter" : "Parameter", "Permission:" : "Berechtigung:", "show up to version:" : "zeige bis zur Version:", - "Success (200)" : "Success (200)", "Type" : "Typ" } }); \ No newline at end of file diff --git a/template_basic/main.js b/template_basic/main.js index ecc5a72c..3972cfc4 100644 --- a/template_basic/main.js +++ b/template_basic/main.js @@ -73,8 +73,12 @@ require([ // Titel der ersten Einträge von group[].name[] ermitteln (name hat Versionsliste) var titles = {}; $.each(groupEntries, function(index, entries) { - var title = entries[0].title.toLowerCase().replace(/[äöüß]/g, function($0) { return umlauts[$0]; }); - titles[title + " #~#" + index] = 1; + var title = entries[0].title; + if(title) + { + title.toLowerCase().replace(/[äöüß]/g, function($0) { return umlauts[$0]; }); + titles[title + " #~#" + index] = 1; + } }); // each // Sortieren var values = Object.keys(titles); @@ -232,9 +236,10 @@ require([ }; } - if(entry.parameter && entry.parameter.fields) fields._hasTypeInParameterFields = _.any(entry.parameter.fields, function(item) { return item.type; }); - if(entry.error && entry.error.fields) fields._hasTypeInErrorFields = _.any(entry.error.fields, function(item) { return item.type; }); - if(entry.success && entry.success.fields) fields._hasTypeInSuccessFields = _.any(entry.success.fields, function(item) { return item.type; }); + if(entry.parameter && entry.parameter.fields) fields._hasTypeInParameterFields = _hasTypeInFields(entry.parameter.fields); + if(entry.error && entry.error.fields) fields._hasTypeInErrorFields = _hasTypeInFields(entry.error.fields); + if(entry.success && entry.success.fields) fields._hasTypeInSuccessFields = _hasTypeInFields(entry.success.fields); + if(entry.info && entry.info.fields) fields._hasTypeInInfoFields = _hasTypeInFields(entry.info.fields); articles.push({ article: templateArticle(fields), @@ -274,6 +279,25 @@ require([ $('html,body').animate({ scrollTop: parseInt($(id).offset().top) - 18 }, 0); } + /** + * Check if Parameter (sub) List has a type Field. + * Example: @apaSuccess varname1 No type. + * @apaSuccess {String} varname2 With type. + * + * @param {Object} fields + */ + function _hasTypeInFields(fields) + { + hasField = false; + $.each(fields, function(name) { + if(_.any(fields[name], function(item) { return item.type; }) ) + { + hasField = true; + } + }); + return hasField; + } // _hasTypeInFields + /** * On Template changes, recall plugins. */ diff --git a/test/fixtures/api_data.js b/test/fixtures/api_data.js index 2c3bae49..86ef8401 100644 --- a/test/fixtures/api_data.js +++ b/test/fixtures/api_data.js @@ -1,40 +1,366 @@ define({ api: [ { "type": "get", - "url": "/log/:id", - "title": "Get", - "description": "Daten eines Logs laden.", + "url": "/test1/:id", + "title": "Get Test 1", + "name": "GetTest1", + "group": "Test", + "version": "0.1.1", + "description": "Test Version 0.1.x\nTest some basic functions.", + "parameter": { + "fields": { + "Parameter": [ + { + "group": "Parameter", + "type": "String", + "field": "param1", + "optional": false, + "description": "Parameter with type and description." + }, + { + "group": "Parameter", + "type": "String", + "field": "param2", + "optional": false, + "description": "" + }, + { + "group": "Parameter", + "type": "String", + "field": "param3", + "defaultValue": "Default Value", + "optional": true, + "description": "Parameter with type, description and default value." + }, + { + "group": "Parameter", + "type": "String", + "field": "param4", + "defaultValue": "Default Value", + "optional": true, + "description": "" + }, + { + "group": "Parameter", + "field": "param5", + "optional": false, + "description": "Basic Parameter with description." + }, + { + "group": "Parameter", + "field": "param6", + "optional": false, + "description": "" + }, + { + "group": "Parameter", + "field": "param7", + "defaultValue": "Default Value", + "optional": true, + "description": "Basic Parameter with description and default value." + }, + { + "group": "Parameter", + "field": "param8", + "defaultValue": "Default Value", + "optional": true, + "description": "" + }, + { + "group": "Parameter", + "field": "param9", + "optional": true, + "description": "Optional basic Parameter with description." + }, + { + "group": "Parameter", + "field": "param10", + "optional": true, + "description": "" + }, + { + "group": "Parameter", + "field": "param11", + "defaultValue": "Default Value", + "optional": true, + "description": "Optional basic Parameter with description and default value." + }, + { + "group": "Parameter", + "field": "param12", + "defaultValue": "Default Value", + "optional": true, + "description": "" + }, + { + "group": "Parameter", + "type": "String", + "field": "param13", + "optional": true, + "description": "Optional Parameter with type and description." + }, + { + "group": "Parameter", + "type": "String", + "field": "param14", + "optional": true, + "description": "" + }, + { + "group": "Parameter", + "type": "String", + "field": "param15", + "defaultValue": "Default Value", + "optional": true, + "description": "Optional Parameter with type, description and default value." + }, + { + "group": "Parameter", + "type": "String", + "field": "param16", + "defaultValue": "Default Value", + "optional": true, + "description": "" + } + ] + } + }, + "filename": "test\\fixtures\\example\\example.js" + }, + { + "type": "get", + "url": "/test1/:id", + "title": "Get Test 1", + "name": "GetTest1", + "group": "Test", + "version": "0.1.0", + "description": "Test Version 0.1.x\nTest some basic functions.", + "parameter": { + "fields": { + "Parameter": [ + { + "group": "Parameter", + "type": "String", + "field": "param0", + "optional": false, + "description": "This param is removed in 0.1.1." + }, + { + "group": "Parameter", + "type": "String", + "field": "param1", + "optional": false, + "description": "This is an old text." + }, + { + "group": "Parameter", + "type": "String", + "field": "param2", + "optional": false, + "description": "" + }, + { + "group": "Parameter", + "type": "String", + "field": "param3", + "defaultValue": "Default Value", + "optional": true, + "description": "Parameter with type, description and default value." + }, + { + "group": "Parameter", + "type": "String", + "field": "param4", + "defaultValue": "Default Value", + "optional": true, + "description": "" + }, + { + "group": "Parameter", + "field": "param5", + "optional": false, + "description": "Basic Parameter with description." + }, + { + "group": "Parameter", + "field": "param6", + "optional": false, + "description": "" + }, + { + "group": "Parameter", + "field": "param7", + "defaultValue": "Default Value", + "optional": true, + "description": "Basic Parameter with description and default value." + }, + { + "group": "Parameter", + "field": "param8", + "defaultValue": "Default Value", + "optional": true, + "description": "" + }, + { + "group": "Parameter", + "field": "param9", + "optional": true, + "description": "Optional basic Parameter with description." + }, + { + "group": "Parameter", + "field": "param10", + "optional": true, + "description": "" + }, + { + "group": "Parameter", + "field": "param11", + "defaultValue": "Default Value", + "optional": true, + "description": "Optional basic Parameter with description and default value." + }, + { + "group": "Parameter", + "field": "param12", + "defaultValue": "Default Value", + "optional": true, + "description": "" + }, + { + "group": "Parameter", + "type": "String", + "field": "param13", + "optional": true, + "description": "Optional Parameter with type and description." + }, + { + "group": "Parameter", + "type": "String", + "field": "param14", + "optional": true, + "description": "" + }, + { + "group": "Parameter", + "type": "String", + "field": "param15", + "defaultValue": "Default Value", + "optional": true, + "description": "Optional Parameter with type, description and default value." + }, + { + "group": "Parameter", + "type": "String", + "field": "param16", + "defaultValue": "Default Value", + "optional": true, + "description": "" + } + ] + } + }, + "filename": "test\\fixtures\\example\\example.js" + }, + { + "type": "get", + "url": "/test2/:id", + "title": "Get Test 2", + "name": "GetTest2", + "group": "Test", "version": "0.2.0", - "permission": "none", + "description": "Test Version 0.2.x\nTest Title and Grouping of param, success, error", "parameter": { - "fields": [ - { - "type": "String", - "field": "param1", - "optional": false, - "description": "Beschreibung Param1" - }, - { - "type": "String", - "field": "param2", - "optional": false - }, - { - "type": "String", - "field": "param3", - "defaultValue": "Default Value", - "optional": true, - "description": "Beschreibung Param3" - }, - { - "type": "String", - "field": "param4", - "defaultValue": "Default Value", - "optional": true - } - ] + "fields": { + "Parameter": [ + { + "group": "Parameter", + "type": "String", + "field": "param1", + "optional": false, + "description": "No Group, automatically set Group to \"Parameter\"" + } + ], + "Replace \"login\" with this text": [ + { + "group": "login", + "type": "String", + "field": "param2", + "optional": false, + "description": "Group \"login\"" + }, + { + "group": "login", + "type": "String", + "field": "param3", + "defaultValue": "Default Value", + "optional": true, + "description": "Group \"login\" with default Value" + } + ] + } + }, + "success": { + "fields": { + "201 - Everything ok, replace \"201\" with this text.": [ + { + "group": "201", + "type": "String", + "field": "success2", + "optional": false, + "description": "Group \"201\"" + }, + { + "group": "201", + "type": "String", + "field": "success3", + "defaultValue": "Default Value", + "optional": true, + "description": "Group \"201\" with default Value" + } + ], + "Success 200": [ + { + "group": "Success 200", + "type": "String", + "field": "success1", + "optional": false, + "description": "No Group, automatically set \"Success 200\"" + } + ] + } + }, + "error": { + "fields": { + "400": [ + { + "group": "400", + "type": "String", + "field": "error2", + "optional": false, + "description": "Group \"400\"" + } + ], + "401 - Oh oh, replace \"401\" with this text": [ + { + "group": "401", + "type": "String", + "field": "error3", + "optional": false, + "description": "Group \"401\"" + } + ], + "Error 4xx": [ + { + "group": "Error 4xx", + "type": "String", + "field": "error1", + "optional": false, + "description": "No Group automatically set \"Error 4xx\"" + } + ] + } }, - "group": "example.js", - "filename": "test/fixtures/example/example.js" + "filename": "test\\fixtures\\example\\example.js" } ] }); \ No newline at end of file diff --git a/test/fixtures/api_data.json b/test/fixtures/api_data.json index 04fb5a2f..26491f33 100644 --- a/test/fixtures/api_data.json +++ b/test/fixtures/api_data.json @@ -1,40 +1,366 @@ [ { "type": "get", - "url": "/log/:id", - "title": "Get", - "description": "Daten eines Logs laden.", + "url": "/test1/:id", + "title": "Get Test 1", + "name": "GetTest1", + "group": "Test", + "version": "0.1.1", + "description": "Test Version 0.1.x\nTest some basic functions.", + "parameter": { + "fields": { + "Parameter": [ + { + "group": "Parameter", + "type": "String", + "field": "param1", + "optional": false, + "description": "Parameter with type and description." + }, + { + "group": "Parameter", + "type": "String", + "field": "param2", + "optional": false, + "description": "" + }, + { + "group": "Parameter", + "type": "String", + "field": "param3", + "defaultValue": "Default Value", + "optional": true, + "description": "Parameter with type, description and default value." + }, + { + "group": "Parameter", + "type": "String", + "field": "param4", + "defaultValue": "Default Value", + "optional": true, + "description": "" + }, + { + "group": "Parameter", + "field": "param5", + "optional": false, + "description": "Basic Parameter with description." + }, + { + "group": "Parameter", + "field": "param6", + "optional": false, + "description": "" + }, + { + "group": "Parameter", + "field": "param7", + "defaultValue": "Default Value", + "optional": true, + "description": "Basic Parameter with description and default value." + }, + { + "group": "Parameter", + "field": "param8", + "defaultValue": "Default Value", + "optional": true, + "description": "" + }, + { + "group": "Parameter", + "field": "param9", + "optional": true, + "description": "Optional basic Parameter with description." + }, + { + "group": "Parameter", + "field": "param10", + "optional": true, + "description": "" + }, + { + "group": "Parameter", + "field": "param11", + "defaultValue": "Default Value", + "optional": true, + "description": "Optional basic Parameter with description and default value." + }, + { + "group": "Parameter", + "field": "param12", + "defaultValue": "Default Value", + "optional": true, + "description": "" + }, + { + "group": "Parameter", + "type": "String", + "field": "param13", + "optional": true, + "description": "Optional Parameter with type and description." + }, + { + "group": "Parameter", + "type": "String", + "field": "param14", + "optional": true, + "description": "" + }, + { + "group": "Parameter", + "type": "String", + "field": "param15", + "defaultValue": "Default Value", + "optional": true, + "description": "Optional Parameter with type, description and default value." + }, + { + "group": "Parameter", + "type": "String", + "field": "param16", + "defaultValue": "Default Value", + "optional": true, + "description": "" + } + ] + } + }, + "filename": "test\\fixtures\\example\\example.js" + }, + { + "type": "get", + "url": "/test1/:id", + "title": "Get Test 1", + "name": "GetTest1", + "group": "Test", + "version": "0.1.0", + "description": "Test Version 0.1.x\nTest some basic functions.", + "parameter": { + "fields": { + "Parameter": [ + { + "group": "Parameter", + "type": "String", + "field": "param0", + "optional": false, + "description": "This param is removed in 0.1.1." + }, + { + "group": "Parameter", + "type": "String", + "field": "param1", + "optional": false, + "description": "This is an old text." + }, + { + "group": "Parameter", + "type": "String", + "field": "param2", + "optional": false, + "description": "" + }, + { + "group": "Parameter", + "type": "String", + "field": "param3", + "defaultValue": "Default Value", + "optional": true, + "description": "Parameter with type, description and default value." + }, + { + "group": "Parameter", + "type": "String", + "field": "param4", + "defaultValue": "Default Value", + "optional": true, + "description": "" + }, + { + "group": "Parameter", + "field": "param5", + "optional": false, + "description": "Basic Parameter with description." + }, + { + "group": "Parameter", + "field": "param6", + "optional": false, + "description": "" + }, + { + "group": "Parameter", + "field": "param7", + "defaultValue": "Default Value", + "optional": true, + "description": "Basic Parameter with description and default value." + }, + { + "group": "Parameter", + "field": "param8", + "defaultValue": "Default Value", + "optional": true, + "description": "" + }, + { + "group": "Parameter", + "field": "param9", + "optional": true, + "description": "Optional basic Parameter with description." + }, + { + "group": "Parameter", + "field": "param10", + "optional": true, + "description": "" + }, + { + "group": "Parameter", + "field": "param11", + "defaultValue": "Default Value", + "optional": true, + "description": "Optional basic Parameter with description and default value." + }, + { + "group": "Parameter", + "field": "param12", + "defaultValue": "Default Value", + "optional": true, + "description": "" + }, + { + "group": "Parameter", + "type": "String", + "field": "param13", + "optional": true, + "description": "Optional Parameter with type and description." + }, + { + "group": "Parameter", + "type": "String", + "field": "param14", + "optional": true, + "description": "" + }, + { + "group": "Parameter", + "type": "String", + "field": "param15", + "defaultValue": "Default Value", + "optional": true, + "description": "Optional Parameter with type, description and default value." + }, + { + "group": "Parameter", + "type": "String", + "field": "param16", + "defaultValue": "Default Value", + "optional": true, + "description": "" + } + ] + } + }, + "filename": "test\\fixtures\\example\\example.js" + }, + { + "type": "get", + "url": "/test2/:id", + "title": "Get Test 2", + "name": "GetTest2", + "group": "Test", "version": "0.2.0", - "permission": "none", + "description": "Test Version 0.2.x\nTest Title and Grouping of param, success, error", "parameter": { - "fields": [ - { - "type": "String", - "field": "param1", - "optional": false, - "description": "Beschreibung Param1" - }, - { - "type": "String", - "field": "param2", - "optional": false - }, - { - "type": "String", - "field": "param3", - "defaultValue": "Default Value", - "optional": true, - "description": "Beschreibung Param3" - }, - { - "type": "String", - "field": "param4", - "defaultValue": "Default Value", - "optional": true - } - ] + "fields": { + "Parameter": [ + { + "group": "Parameter", + "type": "String", + "field": "param1", + "optional": false, + "description": "No Group, automatically set Group to \"Parameter\"" + } + ], + "Replace \"login\" with this text": [ + { + "group": "login", + "type": "String", + "field": "param2", + "optional": false, + "description": "Group \"login\"" + }, + { + "group": "login", + "type": "String", + "field": "param3", + "defaultValue": "Default Value", + "optional": true, + "description": "Group \"login\" with default Value" + } + ] + } + }, + "success": { + "fields": { + "201 - Everything ok, replace \"201\" with this text.": [ + { + "group": "201", + "type": "String", + "field": "success2", + "optional": false, + "description": "Group \"201\"" + }, + { + "group": "201", + "type": "String", + "field": "success3", + "defaultValue": "Default Value", + "optional": true, + "description": "Group \"201\" with default Value" + } + ], + "Success 200": [ + { + "group": "Success 200", + "type": "String", + "field": "success1", + "optional": false, + "description": "No Group, automatically set \"Success 200\"" + } + ] + } + }, + "error": { + "fields": { + "400": [ + { + "group": "400", + "type": "String", + "field": "error2", + "optional": false, + "description": "Group \"400\"" + } + ], + "401 - Oh oh, replace \"401\" with this text": [ + { + "group": "401", + "type": "String", + "field": "error3", + "optional": false, + "description": "Group \"401\"" + } + ], + "Error 4xx": [ + { + "group": "Error 4xx", + "type": "String", + "field": "error1", + "optional": false, + "description": "No Group automatically set \"Error 4xx\"" + } + ] + } }, - "group": "example.js", - "filename": "test/fixtures/example/example.js" + "filename": "test\\fixtures\\example\\example.js" } ] \ No newline at end of file diff --git a/test/fixtures/api_project.js b/test/fixtures/api_project.js index 7ce3c673..5bc72255 100644 --- a/test/fixtures/api_project.js +++ b/test/fixtures/api_project.js @@ -1,10 +1,10 @@ define({ "name": "apidoc", - "version": "0.1.10", + "version": "0.2.0", "description": "RESTful web API Documentation Generator", "apidoc": "", "generator": { - "version": "0.1.10", - "time": "2013-04-12T16:50:18.630Z" + "version": "0.2.0", + "time": "2013-05-30T18:44:56.859Z" } }); \ No newline at end of file diff --git a/test/fixtures/api_project.json b/test/fixtures/api_project.json index 1f80f92e..b8826e58 100644 --- a/test/fixtures/api_project.json +++ b/test/fixtures/api_project.json @@ -1,10 +1,10 @@ { "name": "apidoc", - "version": "0.1.10", + "version": "0.2.0", "description": "RESTful web API Documentation Generator", "apidoc": "", "generator": { - "version": "0.1.10", - "time": "2013-04-12T16:50:18.630Z" + "version": "0.2.0", + "time": "2013-05-30T18:44:56.859Z" } } \ No newline at end of file diff --git a/test/fixtures/example/example.js b/test/fixtures/example/example.js index d7c7e9df..090fd4f5 100644 --- a/test/fixtures/example/example.js +++ b/test/fixtures/example/example.js @@ -5,36 +5,95 @@ /** * @apiIgnore Ignore this block, apiIgnore is set. * @api {get} /ignore/me + * Test whitespaces befor block. */ /** - * @api {get} /log/:id Get - * @apiDescription Daten eines Logs laden. - * test + * @api {get} /test1/:id Get Test 1 + * @apiName GetTest1 + * @apiGroup Test + * @apiVersion 0.1.1 + * @apiDescription Test Version 0.1.x + * Test some basic functions. * - * @apiVersion 0.2.0 - * @apiPermission none - * @apiDescription Daten eines Logs laden. + * @apiParam {String} param1 Parameter with type and description. + * @apiParam {String} param2 + * @apiParam {String} param3="Default Value" Parameter with type, description and default value. + * @apiParam {String} param4="Default Value" + * + * @apiParam param5 Basic Parameter with description. + * @apiParam param6 + * @apiParam param7="Default Value" Basic Parameter with description and default value. + * @apiParam param8="Default Value" + * + * @apiParam [param9] Optional basic Parameter with description. + * @apiParam [param10] + * @apiParam [param11="Default Value"] Optional basic Parameter with description and default value. + * @apiParam [param12="Default Value"] + * + * @apiParam {String} [param13] Optional Parameter with type and description. + * @apiParam {String} [param14] + * @apiParam {String} [param15="Default Value"] Optional Parameter with type, description and default value. + * @apiParam {String} [param16="Default Value"] + */ + +/** + * @api {get} /test1/:id Get Test 1 + * @apiName GetTest1 + * @apiGroup Test + * @apiVersion 0.1.0 + * @apiDescription Test Version 0.1.x + * Test some basic functions. * - * @apiParam {String} param1 Beschreibung Param1 + * @apiParam {String} param0 This param is removed in 0.1.1. + * @apiParam {String} param1 This is an old text. * @apiParam {String} param2 - * @apiParam {String} param3="Default Value" Beschreibung Param3 + * @apiParam {String} param3="Default Value" Parameter with type, description and default value. * @apiParam {String} param4="Default Value" * - * @apiParam param1 Beschreibung Param1 - * @apiParam param2 - * @apiParam param3="Default Value" Beschreibung Param3 - * @apiParam param4="Default Value" + * @apiParam param5 Basic Parameter with description. + * @apiParam param6 + * @apiParam param7="Default Value" Basic Parameter with description and default value. + * @apiParam param8="Default Value" * - * @apiParam [param1] Beschreibung Param1 - * @apiParam [param2] - * @apiParam [param3="Default Value"] Beschreibung Param3 - * @apiParam [param4="Default Value"] + * @apiParam [param9] Optional basic Parameter with description. + * @apiParam [param10] + * @apiParam [param11="Default Value"] Optional basic Parameter with description and default value. + * @apiParam [param12="Default Value"] + * + * @apiParam {String} [param13] Optional Parameter with type and description. + * @apiParam {String} [param14] + * @apiParam {String} [param15="Default Value"] Optional Parameter with type, description and default value. + * @apiParam {String} [param16="Default Value"] + */ + +/** + * @api {get} /test2/:id Get Test 2 + * @apiName GetTest2 + * @apiGroup Test + * @apiVersion 0.2.0 + * @apiDescription Test Version 0.2.x + * Test Title and Grouping of param, success, error * - * @apiParam {String} [param1] Beschreibung Param1 - * @apiParam {String} [param2] - * @apiParam {String} [param3="Default Value"] Beschreibung Param3 - * @apiParam {String} [param4="Default Value"] * - * @api {get} /log/:id Get - */ \ No newline at end of file + * @apiParam {String} param1 No Group, automatically set Group to "Parameter" + * + * @apiParamTitle (login) Replace "login" with this text + * @apiParam (login) {String} param2 Group "login" + * @apiParam (login) {String} param3="Default Value" Group "login" with default Value + * + * + * @apiSuccess {String} success1 No Group, automatically set "Success 200" + * + * @apiSuccessTitle (201) 201 - Everything ok, replace "201" with this text. + * @apiSuccess (201) {String} success2 Group "201" + * @apiSuccess (201) {String} success3="Default Value" Group "201" with default Value + * + * + * @apiError {String} error1 No Group automatically set "Error 4xx" + * + * @apiError (400) {String} error2 Group "400" + * + * @apiErrorTitle (401) 401 - Oh oh, replace "401" with this text + * @apiError (401) {String} error3 Group "401" + */