add templates.useShortNamesInLinks config option (#738)

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.
This commit is contained in:
Jeff Williams 2017-07-23 18:34:32 -07:00
parent 2c47d4b306
commit e8bca1f490
2 changed files with 73 additions and 52 deletions

View File

@ -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.
@ -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) {
@ -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;
@ -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.
*
@ -552,7 +566,8 @@ exports.resolveLinks = function(str) {
return string.replace( tagInfo.completeTag, buildLink(target, linkText, {
linkMap: longnameToUrl,
monospace: monospace
monospace: monospace,
shortenName: shouldShortenLongname()
}) );
}

View File

@ -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;
}
function restoreConfTemplates(storage) {
var keys = Object.keys(storage);
for (var i = 0; i < keys.length; ++i) {
env.conf.templates[keys[i]] = storage[keys[i]];
}
}
describe("resolveLinks", function() {
var conf;
beforeEach(function() {
conf = doop(env.conf.templates);
});
afterEach(function() {
env.conf.templates = conf;
});
it('should translate {@link test} into a HTML link.', function() {
var input = 'This is a {@link test}.';
var output = helper.resolveLinks(input);
@ -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'];
});
});