generate human-readable filenames (#339)

This commit is contained in:
Jeff Williams 2013-02-19 07:02:08 -08:00
parent 9d13a1e6bb
commit dfe917a35a
2 changed files with 21 additions and 14 deletions

View File

@ -3,7 +3,6 @@
* @module jsdoc/util/templateHelper * @module jsdoc/util/templateHelper
*/ */
var crypto = require('crypto');
var dictionary = require('jsdoc/tag/dictionary'); var dictionary = require('jsdoc/tag/dictionary');
var util = require('util'); var util = require('util');
@ -14,7 +13,6 @@ var files = {};
// each container gets its own html file // each container gets its own html file
var containers = ['class', 'module', 'external', 'namespace', 'mixin']; var containers = ['class', 'module', 'external', 'namespace', 'mixin'];
/** @external {jsdoc.tutorial.Tutorial} */
var tutorials; var tutorials;
/** Sets tutorials map. /** Sets tutorials map.
@ -68,18 +66,25 @@ var nsprefix = /^(event|module|external):/;
* @return {string} The filename to use for the string. * @return {string} The filename to use for the string.
*/ */
var getUniqueFilename = exports.getUniqueFilename = function(str) { var getUniqueFilename = exports.getUniqueFilename = function(str) {
var result;
// allow for namespace prefix // allow for namespace prefix
var basename = str.replace(nsprefix, '$1-'); var basename = str.replace(nsprefix, '$1-')
// and use - instead of ~ to denote 'inner'
.replace(/~/g, '-');
if ( /[^$a-z0-9._\-]/i.test(basename) ) { // if the basename includes characters that we can't use in a filepath, remove everything up to
result = crypto.createHash('sha1').update(str).digest('hex').substr(0, 10); // and including the last bad character
} else { var regexp = /[^$a-z0-9._\-](?=[$a-z0-9._\-]*$)/i;
result = makeFilenameUnique(basename, str); var result = regexp.exec(basename);
if (result && result.index) {
basename = basename.substr(result.index + 1);
} }
return result + exports.fileExtension; // make sure we don't create hidden files on POSIX systems
basename = basename.replace(/^\./, '');
// and in case we've now stripped the entire basename (uncommon, but possible):
basename = basename.length ? basename : '_';
return makeFilenameUnique(basename, str) + exports.fileExtension;
}; };
// two-way lookup // two-way lookup

View File

@ -140,14 +140,16 @@ describe("jsdoc/util/templateHelper", function() {
// disabled because Jasmine appears to execute this code twice, which causes getUniqueFilename // disabled because Jasmine appears to execute this code twice, which causes getUniqueFilename
// to return an unexpected variation on the name the second time // to return an unexpected variation on the name the second time
xdescribe("getUniqueFilename", function() { xdescribe("getUniqueFilename", function() {
// TODO: needs more tests for unusual values and things that get special treatment (such as
// inner members)
it('should convert a simple string into the string plus the default extension', function() { it('should convert a simple string into the string plus the default extension', function() {
var filename = helper.getUniqueFilename('BackusNaur'); var filename = helper.getUniqueFilename('BackusNaur');
expect(filename).toEqual('BackusNaur.html'); expect(filename).toEqual('BackusNaur.html');
}); });
it('should convert a string with slashes into an alphanumeric hash plus the default extension', function() { it('should convert a string with slashes into the text following the last slash plus the default extension', function() {
var filename = helper.getUniqueFilename('tick/tock'); var filename = helper.getUniqueFilename('tick/tock');
expect(filename).toMatch(/^[A-Za-z0-9]+\.html$/); expect(filename).toMatch(/^tock\.html$/);
}); });
it('should not return the same filename twice', function() { it('should not return the same filename twice', function() {
@ -743,7 +745,7 @@ describe("jsdoc/util/templateHelper", function() {
expect(newUrl).toEqual(nestedNamespaceUrl); expect(newUrl).toEqual(nestedNamespaceUrl);
}); });
it('should create a url for a name with invalid characters using a digest.', function() { it('should create a url for a name with invalid characters.', function() {
var mockDoclet = { var mockDoclet = {
kind: 'function', kind: 'function',
longname: 'ns1."!"."*foo"', longname: 'ns1."!"."*foo"',
@ -752,7 +754,7 @@ describe("jsdoc/util/templateHelper", function() {
}, },
url = helper.createLink(mockDoclet); url = helper.createLink(mockDoclet);
expect(url).toEqual('be9d9563a3.html#"*foo"'); expect(url).toEqual('_.html#"*foo"');
}); });
}); });
}); });