Skip to content

Commit

Permalink
add templates.useShortNamesInLinks config option (#738)
Browse files Browse the repository at this point in the history
When this option is set to `true`, the `{@link}`, `{@linkcode}`, and `{@linkplain}` tags will use the short name, not the longname, as the link text. For example, `{@link foo.bar.baz}` will result in the link text `baz`.

This option has no effect when link text is provided as part of the tag (for example, `{@link foo.bar.baz My link text here}`).

As part of this change, I also simplified many of the tests for the `resolveLinks` method.
  • Loading branch information
hegemonic committed Jul 24, 2017
1 parent 2c47d4b commit e8bca1f
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 50 deletions.
19 changes: 17 additions & 2 deletions lib/jsdoc/util/templateHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,10 @@ function fragmentHash(fragmentId) {
return '#' + fragmentId;
}

function getShortName(longname) {
return name.shorten(longname).name;
}

/**
* Build an HTML link to the symbol with the specified longname. If the longname is not
* associated with a URL, this method simply returns the link text, if provided, or the longname.
Expand All @@ -308,6 +312,8 @@ function fragmentHash(fragmentId) {
* @param {string=} options.linkMap - The link map in which to look up the longname.
* @param {boolean=} options.monospace - Indicates whether to display the link text in a monospace
* font.
* @param {boolean=} options.shortenName - Indicates whether to extract the short name from the
* longname and display the short name in the link text. Ignored if `linkText` is specified.
* @return {string} The HTML link, or the link text if the link is not available.
*/
function buildLink(longname, linkText, options) {
Expand Down Expand Up @@ -337,7 +343,7 @@ function buildLink(longname, linkText, options) {
}
else {
fileUrl = hasOwnProp.call(options.linkMap, longname) ? options.linkMap[longname] : '';
text = linkText || longname;
text = linkText || (options.shortenName ? getShortName(longname) : longname);
}

text = options.monospace ? '<code>' + text + '</code>' : text;
Expand Down Expand Up @@ -503,6 +509,14 @@ var toTutorial = exports.toTutorial = function(tutorial, content, missingOpts) {
return '<a href="' + tutorialToUrl(tutorial) + '">' + content + '</a>';
};

function shouldShortenLongname() {
if (env.conf && env.conf.templates && env.conf.templates.useShortNamesInLinks) {
return true;
}

return false;
}

/**
* Find `{@link ...}` and `{@tutorial ...}` inline tags and turn them into HTML links.
*
Expand Down Expand Up @@ -552,7 +566,8 @@ exports.resolveLinks = function(str) {

return string.replace( tagInfo.completeTag, buildLink(target, linkText, {
linkMap: longnameToUrl,
monospace: monospace
monospace: monospace,
shortenName: shouldShortenLongname()
}) );
}

Expand Down
102 changes: 54 additions & 48 deletions test/specs/jsdoc/util/templateHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -1432,30 +1432,17 @@ describe("jsdoc/util/templateHelper", function() {
});
});

// couple of convenience functions letting me set conf variables and restore
// them back to the originals later.
function setConfTemplatesVariables(hash) {
var keys = Object.keys(hash);
var storage = {};

for (var i = 0; i < keys.length; ++i) {
storage[keys[i]] = env.conf.templates[keys[i]];
// works because hash[key] is a scalar not an array/object
env.conf.templates[keys[i]] = hash[keys[i]];
}

return storage;
}
describe("resolveLinks", function() {
var conf;

function restoreConfTemplates(storage) {
var keys = Object.keys(storage);
beforeEach(function() {
conf = doop(env.conf.templates);
});

for (var i = 0; i < keys.length; ++i) {
env.conf.templates[keys[i]] = storage[keys[i]];
}
}
afterEach(function() {
env.conf.templates = conf;
});

describe("resolveLinks", function() {
it('should translate {@link test} into a HTML link.', function() {
var input = 'This is a {@link test}.';
var output = helper.resolveLinks(input);
Expand Down Expand Up @@ -1606,84 +1593,103 @@ describe("jsdoc/util/templateHelper", function() {
// conf.monospaceLinks. check that
// a) it works
it('if conf.monospaceLinks is true, all {@link} should be monospace', function() {
var storage = setConfTemplatesVariables({monospaceLinks: true});
var input = 'Link to {@link test}';
var output = helper.resolveLinks(input);
var output;

env.conf.templates.monospaceLinks = true;
output = helper.resolveLinks(input);

expect(output).toBe('Link to <a href="path/to/test.html"><code>test</code></a>');
restoreConfTemplates(storage);
});

// b) linkcode and linkplain are still respected
it('if conf.monospaceLinks is true, all {@linkcode} should still be monospace', function() {
var storage = setConfTemplatesVariables({monospaceLinks: true});
var input = 'Link to {@linkcode test}';
var output = helper.resolveLinks(input);
var output;

env.conf.templates.monospaceLinks = true;
output = helper.resolveLinks(input);

expect(output).toBe('Link to <a href="path/to/test.html"><code>test</code></a>');
restoreConfTemplates(storage);
});

it('if conf.monospaceLinks is true, all {@linkplain} should still be plain', function() {
var storage = setConfTemplatesVariables({monospaceLinks: true});
var input = 'Link to {@linkplain test}';
var output = helper.resolveLinks(input);
var output;

env.conf.templates.monospaceLinks = true;
output = helper.resolveLinks(input);

expect(output).toBe('Link to <a href="path/to/test.html">test</a>');
restoreConfTemplates(storage);
});

// conf.cleverLinks. check that
// a) it works
it('if conf.cleverLinks is true, {@link symbol} should be in monospace', function() {
var storage = setConfTemplatesVariables({cleverLinks: true});
var input = 'Link to {@link test}';
var output = helper.resolveLinks(input);
var output;

env.conf.templates.cleverLinks = true;
output = helper.resolveLinks(input);

expect(output).toBe('Link to <a href="path/to/test.html"><code>test</code></a>');
restoreConfTemplates(storage);
});

it('if conf.cleverLinks is true, {@link URL} should be in plain text', function() {
var storage = setConfTemplatesVariables({cleverLinks: true});
var input = 'Link to {@link http://github.com}';
var output = helper.resolveLinks(input);
var output;

env.conf.templates.cleverLinks = true;
output = helper.resolveLinks(input);

expect(output).toBe('Link to <a href="http://github.com">http://github.com</a>');
restoreConfTemplates(storage);
});

// b) linkcode and linkplain are still respected
it('if conf.cleverLinks is true, all {@linkcode} should still be clever', function() {
var storage = setConfTemplatesVariables({cleverLinks: true});
var input = 'Link to {@linkcode test}';
var output = helper.resolveLinks(input);
var output;

env.conf.templates.cleverLinks = true;
output = helper.resolveLinks(input);

expect(output).toBe('Link to <a href="path/to/test.html"><code>test</code></a>');
restoreConfTemplates(storage);
});

it('if conf.cleverLinks is true, all {@linkplain} should still be plain', function() {
var storage = setConfTemplatesVariables({cleverLinks: true});
var input = 'Link to {@linkplain test}';
var output = helper.resolveLinks(input);
var output;

env.conf.templates.cleverLinks = true;
output = helper.resolveLinks(input);

expect(output).toBe('Link to <a href="path/to/test.html">test</a>');
restoreConfTemplates(storage);
});

// c) if monospaceLinks is additionally `true` it is ignored in favour
// of cleverLinks
it('if conf.cleverLinks is true and so is conf.monospaceLinks, cleverLinks overrides', function() {
var storage = setConfTemplatesVariables({
cleverLinks: true,
monospaceLinks: true
});
var input = 'Link to {@link test} and {@link http://github.com}';
var output = helper.resolveLinks(input);
var output;

env.conf.templates.cleverLinks = true;
env.conf.templates.monospaceLinks = true;
output = helper.resolveLinks(input);

expect(output).toBe('Link to <a href="path/to/test.html"><code>test</code></a> and <a href="http://github.com">http://github.com</a>');
restoreConfTemplates(storage);
});

it('if conf.useShortNamesInLinks is true, it uses the short name in links', function() {
var input = 'Link to {@link my.long.namespace}';
var output;

env.conf.templates.useShortNamesInLinks = true;
helper.registerLink('my.long.namespace', 'asdf.html');
output = helper.resolveLinks(input);

expect(output).toBe('Link to <a href="asdf.html">namespace</a>');

delete helper.longnameToUrl['my.long.namespace'];
});
});

Expand Down

0 comments on commit e8bca1f

Please sign in to comment.