fix(prefixHeaderId): make prefixHeaderId string be parsed along the generated id

If an invalid prefix was passed (a string with spaces, for instance),
the string would be added as is. This ould generate invalid ids.
Also, this makes `prefixHeaderId` option play nicely with `ghCompatibleHeaderId`, since they will
follow the same escaping rules when both options are enabled.
This commit is contained in:
Estevao Soares dos Santos 2017-02-06 05:37:49 +00:00
parent 41cb3f6b7f
commit f641a7de90
14 changed files with 33 additions and 18 deletions

BIN
dist/showdown.js vendored

Binary file not shown.

BIN
dist/showdown.js.map vendored

Binary file not shown.

BIN
dist/showdown.min.js vendored

Binary file not shown.

Binary file not shown.

View File

@ -3,8 +3,7 @@ showdown.subParser('headers', function (text, options, globals) {
text = globals.converter._dispatch('headers.before', text, options, globals);
var prefixHeader = options.prefixHeaderId,
headerLevelStart = (isNaN(parseInt(options.headerLevelStart))) ? 1 : parseInt(options.headerLevelStart),
var headerLevelStart = (isNaN(parseInt(options.headerLevelStart))) ? 1 : parseInt(options.headerLevelStart),
ghHeaderId = options.ghCompatibleHeaderId,
// Set text-style headers:
@ -53,10 +52,18 @@ showdown.subParser('headers', function (text, options, globals) {
});
function headerId (m) {
var title, escapedId;
var title;
// Prefix id to prevent causing inadvertent pre-existing style matches.
if (showdown.helper.isString(options.prefixHeaderId)) {
title = options.prefixHeaderId + m;
} else if (options.prefixHeaderId === true) {
title = 'section ' + m;
} else {
title = m;
}
if (ghHeaderId) {
escapedId = m
title = title
.replace(/ /g, '-')
// replace previously escaped chars (&, ¨ and $)
.replace(/&/g, '')
@ -67,23 +74,15 @@ showdown.subParser('headers', function (text, options, globals) {
.replace(/[&+$,\/:;=?@"#{}|^¨~\[\]`\\*)(%.!'<>]/g, '')
.toLowerCase();
} else {
escapedId = m.replace(/[^\w]/g, '').toLowerCase();
title = title
.replace(/[^\w]/g, '')
.toLowerCase();
}
if (globals.hashLinkCounts[escapedId]) {
title = escapedId + '-' + (globals.hashLinkCounts[escapedId]++);
if (globals.hashLinkCounts[title]) {
title = title + '-' + (globals.hashLinkCounts[title]++);
} else {
title = escapedId;
globals.hashLinkCounts[escapedId] = 1;
}
// Prefix id to prevent causing inadvertent pre-existing style matches.
if (prefixHeader === true) {
prefixHeader = 'section';
}
if (showdown.helper.isString(prefixHeader)) {
return prefixHeader + title;
globals.hashLinkCounts[title] = 1;
}
return title;
}

View File

@ -0,0 +1 @@
<h1 id="sectionfooheader">foo header</h1>

View File

@ -0,0 +1 @@
# foo header

View File

@ -0,0 +1 @@
<h1 id="my-prefix-foo-header">foo header</h1>

View File

@ -0,0 +1 @@
# foo header

View File

@ -0,0 +1 @@
<h1 id="my-prefix-foo-header">foo header</h1>

View File

@ -0,0 +1 @@
# foo header

View File

@ -0,0 +1 @@
<h1 id="myprefixfooheader">foo header</h1>

View File

@ -0,0 +1 @@
# foo header

View File

@ -61,6 +61,14 @@ describe('makeHtml() features testsuite', function () {
converter = new showdown.Converter({encodeEmails: false, simplifiedAutoLink: true});
} else if (testsuite[i].name === '#331.allow-escaping-of-tilde') {
converter = new showdown.Converter({strikethrough: true});
} else if (testsuite[i].name === 'prefixHeaderId-simple') {
converter = new showdown.Converter({prefixHeaderId: true});
} else if (testsuite[i].name === 'prefixHeaderId-string') {
converter = new showdown.Converter({prefixHeaderId: 'my-prefix-'});
} else if (testsuite[i].name === 'prefixHeaderId-string-and-ghCompatibleHeaderId') {
converter = new showdown.Converter({prefixHeaderId: 'my-prefix-', ghCompatibleHeaderId: true});
} else if (testsuite[i].name === 'prefixHeaderId-string-and-ghCompatibleHeaderId2') {
converter = new showdown.Converter({prefixHeaderId: 'my prefix ', ghCompatibleHeaderId: true});
} else {
converter = new showdown.Converter();
}