diff --git a/lib/jsdoc/tag.js b/lib/jsdoc/tag.js index 7732e3af..7043028f 100644 --- a/lib/jsdoc/tag.js +++ b/lib/jsdoc/tag.js @@ -22,11 +22,19 @@ var jsdoc = { } }; -function trim(text, newlines) { +function trim(text, newlines, outdent) { if (!text) { return ''; } if (newlines) { - return text.replace(/^[\n\r\f]+|[\n\r\f]+$/g, ''); + text = text.replace(/^[\n\r\f]+|[\n\r\f]+$/g, ''); + if (outdent) { + var match = text.match(/^([ \t]+)/); + if (match && match[1]) { + var outdenter = new RegExp('^' + match[1], 'gm'); + text = text.replace(outdenter, ''); + } + } + return text; } else { return text.replace(/^\s+|\s+$/g, ''); @@ -94,7 +102,7 @@ var Tag = exports.Tag = function(tagTitle, tagBody, meta) { var tagDef = jsdoc.tag.dictionary.lookUp(this.title); /** The text part of the tag: @title text */ - this.text = trim(tagBody, tagDef.keepsWhitespace); + this.text = trim(tagBody, tagDef.keepsWhitespace, tagDef.removesIndent); if (this.text) { processTagText(this, tagDef); diff --git a/lib/jsdoc/tag/dictionary/definitions.js b/lib/jsdoc/tag/dictionary/definitions.js index f11f4a85..05af7eb7 100644 --- a/lib/jsdoc/tag/dictionary/definitions.js +++ b/lib/jsdoc/tag/dictionary/definitions.js @@ -297,6 +297,7 @@ exports.defineTags = function(dictionary) { dictionary.defineTag('example', { keepsWhitespace: true, + removesIndent: true, mustHaveValue: true, onTagged: function(doclet, tag) { if (!doclet.examples) { doclet.examples = []; } diff --git a/test/specs/jsdoc/tag.js b/test/specs/jsdoc/tag.js index a324a9c3..3926956f 100644 --- a/test/specs/jsdoc/tag.js +++ b/test/specs/jsdoc/tag.js @@ -25,7 +25,7 @@ describe("jsdoc/tag", function() { ' * myFunction(3, 4); // returns 7\n'; var tagArg = new jsdoc.tag.Tag('arg ', text, meta), // <-- a symonym of param, space in the title. tagParam = new jsdoc.tag.Tag('param', '[foo=1]', meta), // no type, but has optional and defaultvalue. - tagEg = new jsdoc.tag.Tag('example', textEg, meta), // <-- for keepsWhitespace + tagEg = new jsdoc.tag.Tag('example', textEg, meta), // <-- for keepsWhitespace and removesIndent tagType = new jsdoc.tag.Tag('type', 'MyType ', meta); // <-- for onTagText it("should have a 'originalTitle' property, a string", function() { @@ -60,11 +60,31 @@ describe("jsdoc/tag", function() { }); describe("'text' property", function() { + + function trim(text, newlines, outdent) { + if (!text) { return ''; } + + if (newlines) { + text = text.replace(/^[\n\r\f]+|[\n\r\f]+$/g, ''); + if (outdent) { + var match = text.match(/^([ \t]+)/); + if (match && match[1]) { + var outdenter = new RegExp('^' + match[1], 'gm'); + text = text.replace(outdenter, ''); + } + } + return text; + } + else { + return text.replace(/^\s+|\s+$/g, ''); + } + } + it("'text' property should be the trimmed tag text, with all leading and trailing space removed unless tagDef.keepsWhitespace", function() { - // @example has keepsWhitespace, @param doesn't. - // should realy use module:jsdoc/tag~trim here but it's private. - expect(tagArg.text).toBe(text.replace(/^\s+|\s+$/g, '')); - expect(tagEg.text).toBe(textEg.replace(/^[\n\r\f]+|[\n\r\f]+$/g, '')); + // @example has keepsWhitespace and removesIndent, @param doesn't. + // should realy use module:jsdoc/tag~trim here but it's private, so the function is copied locally. + expect(tagArg.text).toBe(trim(text)); + expect(tagEg.text).toBe(trim(textEg, true, true)); }); it("'text' property should have onTagText run on it if it has it.", function() {