Skip to content

Commit

Permalink
feat(uniqueHeaderId): add unique id prefix and suffix to headers
Browse files Browse the repository at this point in the history
If two headers have similar texts, the generated id could be equal. In order to prevent id clash:
  - A unique suffix is added if a header id already exists
  - Option to add a prefix to header id
  - Update of correspondent tests
  - (credits to nicovalencia)

Closes #81, closes #82
  • Loading branch information
tivie committed Jan 18, 2015
1 parent c9de4b6 commit c367a4b
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 13 deletions.
39 changes: 34 additions & 5 deletions dist/showdown.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/showdown.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/showdown.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/showdown.min.js.map

Large diffs are not rendered by default.

15 changes: 12 additions & 3 deletions src/showdown.js
Expand Up @@ -6,7 +6,8 @@
var showdown = {},
parsers = {},
globalOptions = {
omitExtraWLInCodeBlocks: false
omitExtraWLInCodeBlocks: false,
prefixHeaderId: false
};

///////////////////////////////////////////////////////////////////////////
Expand All @@ -29,10 +30,17 @@ showdown.extensions = {};
//Public methods
showdown.setOption = function (key, value) {
globalOptions[key] = value;

return this;
};

showdown.getOption = function (key) {
return globalOptions[key];
};

showdown.getOptions = function () {
return globalOptions;
};

/**
* Static Method
*
Expand Down Expand Up @@ -97,7 +105,8 @@ showdown.Converter = function (converterOptions) {
gHtmlBlocks: [],
gUrls: {},
gTitles: {},
gListLevel: 0
gListLevel: 0,
hashLinkCounts: {}
};

// attacklab: Replace ~ with ~T
Expand Down
22 changes: 21 additions & 1 deletion src/subParsers/headers.js
Expand Up @@ -5,6 +5,8 @@
showdown.subParser('headers', function (text, options, globals) {
'use strict';

var prefixHeader = options.prefixHeaderId;

// Set text-style headers:
// Header 1
// ========
Expand Down Expand Up @@ -52,7 +54,25 @@ showdown.subParser('headers', function (text, options, globals) {
});

function headerId(m) {
return m.replace(/[^\w]/g, '').toLowerCase();
var title,
escapedId = m.replace(/[^\w]/g, '').toLowerCase();

if (globals.hashLinkCounts[escapedId]) {
title = escapedId + '-' + (globals.hashLinkCounts[escapedId]++);
} 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;
}
return title;
}

return text;
Expand Down
5 changes: 5 additions & 0 deletions test/cases/repeated-headers.html
@@ -0,0 +1,5 @@
<h1 id="sametitle">Same Title</h1>

<p>some text</p>

<h1 id="sametitle-1">Same Title</h1>
5 changes: 5 additions & 0 deletions test/cases/repeated-headers.md
@@ -0,0 +1,5 @@
# Same Title

some text

# Same Title

0 comments on commit c367a4b

Please sign in to comment.