require name/description separators to start on the same line as the name (#459)

ensures we won't interpret a Markdown bullet on the following line as a
name/description separator
This commit is contained in:
Jeff Williams 2013-09-20 08:37:44 -07:00
parent 687aceec04
commit b31db5bab9
3 changed files with 40 additions and 42 deletions

View File

@ -123,6 +123,7 @@ function quoteUnsafe(name, kind) { // docspaced names may have unsafe characters
return name;
}
// TODO: make this a private method, or remove it if possible
RegExp.escape = RegExp.escape || function(str) {
var specials = new RegExp("[.*+?|()\\[\\]{}\\\\]", "g"); // .*+?|()[]{}\
return str.replace(specials, "\\$&");
@ -216,44 +217,17 @@ exports.shorten = function(longname, forcedMemberof) {
};
/**
Split a string that starts with a name and ends with a description, into its parts.
Split a string that starts with a name and ends with a description into its parts.
@param {string} nameDesc
@returns {object} Hash with "name" and "description" properties.
*/
exports.splitName = function(nameDesc) {
var name = '',
desc = '',
thisChar = '',
inQuote = false;
for (var i = 0, len = nameDesc.length; i < len; i++) {
thisChar = nameDesc.charAt(i);
if (thisChar === '\\') {
name += thisChar + nameDesc.charAt(++i);
continue;
}
if (thisChar === '"') {
inQuote = !inQuote;
}
if (inQuote) {
name += thisChar;
continue;
}
if (!inQuote) {
if ( /\s/.test(thisChar) ) {
desc = nameDesc.substr(i);
desc = desc.replace(/^[\s\-\s]+/, '').trim();
break;
}
else {
name += thisChar;
}
}
}
return { name: name, description: desc };
// like: name, [name], name text, [name] text, name - text, or [name] - text
// the hyphen must be on the same line as the name; this prevents us from treating a Markdown
// dash as a separator
nameDesc.match(/^(\[[^\]]+\]|\S+)((?:[ \t]*\-\s*|\s+)(\S[\s\S]*))?$/);
return {
name: RegExp.$1,
description: RegExp.$3
};
};

View File

@ -6,6 +6,13 @@
* @license Apache License 2.0 - See file 'LICENSE.md' in this project.
*/
var jsdoc = {
name: require('jsdoc/name'),
tag: {
inline: require('jsdoc/tag/inline')
}
};
/**
* Information about a type expression extracted from tag text.
*
@ -83,6 +90,7 @@ function getTagInfo(tagValue, canHaveName, canHaveType) {
var typeExpression = '';
var text = tagValue;
var expressionAndText;
var nameAndDescription;
var typeOverride;
if (canHaveType) {
@ -92,15 +100,14 @@ function getTagInfo(tagValue, canHaveName, canHaveType) {
}
if (canHaveName) {
// like: name, [name], name text, [name] text, name - text, or [name] - text
text.match(/^(\[[^\]]+\]|\S+)((?:\s*\-\s*|\s+)(\S[\s\S]*))?$/);
name = RegExp.$1;
text = RegExp.$3;
nameAndDescription = jsdoc.name.splitName(text);
name = nameAndDescription.name;
text = nameAndDescription.description;
}
// an inline @type tag, like {@type Foo}, overrides the type expression
if (canHaveType) {
typeOverride = require('jsdoc/tag/inline').extractInlineTag(text, 'type');
typeOverride = jsdoc.tag.inline.extractInlineTag(text, 'type');
if (typeOverride.tags && typeOverride.tags[0]) {
typeExpression = typeOverride.tags[0].text || typeExpression;
}
@ -134,6 +141,7 @@ function getTagInfo(tagValue, canHaveName, canHaveType) {
* can vary (for example, in a function that accepts any number of parameters).
*/
// TODO: move to module:jsdoc/name?
/**
* Extract JSDoc-style type information from the name specified in the tag info, including the
* member name; whether the member is optional; and the default value of the member.

View File

@ -85,7 +85,7 @@ describe("jsdoc/name", function() {
expect(parts.memberof).toEqual('channels."#ops"');
expect(parts.scope).toEqual('#');
startName = 'channels["#bots"]["log.max"]',
startName = 'channels["#bots"]["log.max"]';
parts = jsdoc.name.shorten(startName);
expect(parts.name).toEqual('"log.max"');
@ -174,6 +174,22 @@ describe("jsdoc/name", function() {
expect(parts.name, 'ns.Page#"last \\"sentence\\"".words~sort(2)');
expect(parts.description, 'This is a description.');
});
it('should strip the separator when the separator starts on the same line as the name', function() {
var startName = 'socket - The networking kind, not the wrench.';
var parts = jsdoc.name.splitName(startName);
expect(parts.name).toBe('socket');
expect(parts.description).toBe('The networking kind, not the wrench.');
});
it('should not strip a separator that is preceded by a line break', function() {
var startName = 'socket\n - The networking kind, not the wrench.';
var parts = jsdoc.name.splitName(startName);
expect(parts.name).toBe('socket');
expect(parts.description).toBe('- The networking kind, not the wrench.');
});
});
describe("resolve", function() {