Skip to content

Commit ff26c08

Browse files
committed
feat(rawPrefixHeaderId): add option to prevent showdown from modifying the prefix
Setting this option to true will prevent showdown from modifying the prefix. This might result in malformed IDs (if, for instance, the " char is used in the prefix). Has no effect if prefixHeaderId is set to false. Closes #409
1 parent 5284439 commit ff26c08

File tree

10 files changed

+96
-32
lines changed

10 files changed

+96
-32
lines changed

README.md

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010

1111
------
1212

13-
Showdown is a Javascript Markdown to HTML converter, based on the original works by John Gruber. Showdown can be used client side (in the browser) or server side (with NodeJs).
13+
Showdown is a Javascript Markdown to HTML converter, based on the original works by John Gruber.
14+
Showdown can be used client side (in the browser) or server side (with NodeJs).
1415

1516
## Live DEMO
1617

@@ -28,7 +29,8 @@ Check a live Demo here http://showdownjs.github.io/demo/
2829

2930
## Donate [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.me/tiviesantos)
3031

31-
We're currently looking to improve showdown with automated tests in all browsers and a proper domain and webpage. [If you like our work, please donate!!](https://www.paypal.me/tiviesantos) Your contribution will be greatly appreciated.
32+
We're currently looking to improve showdown with automated tests in all browsers and a proper domain and webpage.
33+
[If you like our work, please donate!!](https://www.paypal.me/tiviesantos) Your contribution will be greatly appreciated.
3234

3335
## Installation
3436

@@ -75,7 +77,8 @@ Showdown has been tested successfully with:
7577
* Netscape 8.1.2
7678
* Konqueror 3.5.4
7779

78-
In theory, Showdown will work in any browser that supports ECMA 262 3rd Edition (JavaScript 1.5). The converter itself might even work in things that aren't web browsers, like Acrobat. No promises.
80+
In theory, Showdown will work in any browser that supports ECMA 262 3rd Edition (JavaScript 1.5).
81+
The converter itself might even work in things that aren't web browsers, like Acrobat. No promises.
7982

8083

8184
## Node compatibility
@@ -196,19 +199,27 @@ var defaultOptions = showdown.getDefaultOptions();
196199
<code><pre>var foo = 'bar';</pre></code>
197200
```
198201
199-
* **noHeaderId**: (boolean) [default false] Disable the automatic generation of header ids. Setting to true overrides **prefixHeaderId**
202+
* **noHeaderId**: (boolean) [default false] Disable the automatic generation of header ids.
203+
Setting to true overrides **prefixHeaderId**
200204
201205
* **customizedHeaderId**: (boolean) [default false] Use text in curly braces as header id. **(since v1.7.0)**
202206
Example:
203207
```
204208
## Sample header {real-id} will use real-id as id
205209
```
206210
207-
* **ghCompatibleHeaderId**: (boolean) [default false] Generate header ids compatible with github style (spaces are replaced with dashes and a bunch of non alphanumeric chars are removed) **(since v1.5.5)**
211+
* **ghCompatibleHeaderId**: (boolean) [default false] Generate header ids compatible with github style
212+
(spaces are replaced with dashes and a bunch of non alphanumeric chars are removed) **(since v1.5.5)**
208213
209-
* **prefixHeaderId**: (string/boolean) [default false] Add a prefix to the generated header ids. Passing a string will prefix that string to the header id. Setting to `true` will add a generic 'section' prefix.
214+
* **prefixHeaderId**: (string/boolean) [default false] Add a prefix to the generated header ids.
215+
Passing a string will prefix that string to the header id. Setting to `true` will add a generic 'section' prefix.
210216
211-
* **rawHeaderId**: (boolean) [default false] Remove only spaces, ' and " from generated header ids (including prefixes), replacing them with dashes (-). WARNING: This might result in malformed ids **(since v1.7.3)**
217+
* **rawPrefixHeaderId**: (boolean) [default false] Setting this option to true will prevent showdown from modifying the prefix.
218+
This might result in malformed IDs (if, for instance, the " char is used in the prefix).
219+
Has no effect if prefixHeaderId is set to false.**(since v 1.7.3)**
220+
221+
* **rawHeaderId**: (boolean) [default false] Remove only spaces, ' and " from generated header ids (including prefixes),
222+
replacing them with dashes (-). WARNING: This might result in malformed ids **(since v1.7.3)**
212223
213224
* **parseImgDimensions**: (boolean) [default false] Enable support for setting image dimensions from within markdown syntax.
214225
Examples:
@@ -229,7 +240,8 @@ var defaultOptions = showdown.getDefaultOptions();
229240
<h3>foo</h3>
230241
```
231242
232-
* **simplifiedAutoLink**: (boolean) [default false] Turning this option on will enable automatic linking to urls. This means that
243+
* **simplifiedAutoLink**: (boolean) [default false] Turning this option on will enable automatic linking to urls.
244+
This means that:
233245
234246
```md
235247
some text www.google.com
@@ -302,12 +314,15 @@ var defaultOptions = showdown.getDefaultOptions();
302314
```
303315
* **smoothLivePreview**: (boolean) [default false] Prevents weird effects in live previews due to incomplete input
304316
305-
* **smartIndentationFix**: (boolean) [default false] Tries to smartly fix indentation problems related to es6 template strings in the midst of indented code.
317+
* **smartIndentationFix**: (boolean) [default false] Tries to smartly fix indentation problems related to es6 template
318+
strings in the midst of indented code.
306319
307-
* **disableForced4SpacesIndentedSublists**: (boolean) [default false] Disables the requirement of indenting sublists by 4 spaces for them to be nested,
308-
effectively reverting to the old behavior where 2 or 3 spaces were enough. **(since v1.5.0)**
320+
* **disableForced4SpacesIndentedSublists**: (boolean) [default false] Disables the requirement of indenting sublists
321+
by 4 spaces for them to be nested, effectively reverting to the old behavior where 2 or 3 spaces were enough.
322+
**(since v1.5.0)**
309323
310-
* **simpleLineBreaks**: (boolean) [default false] Parses line breaks as <br> like GitHub does, without needing 2 spaces at the end of the line **(since v1.5.1)**
324+
* **simpleLineBreaks**: (boolean) [default false] Parses line breaks as <br> like GitHub does, without
325+
needing 2 spaces at the end of the line **(since v1.5.1)**
311326
312327
```md
313328
a line
@@ -325,14 +340,16 @@ var defaultOptions = showdown.getDefaultOptions();
325340
326341
* **ghMentions**: (boolean) [default false] Enables github @mentions, which link to the username mentioned **(since v1.6.0)**
327342
328-
* **ghMentionsLink**: (string) [default `https://github.com/{u}`] Changes the link generated by @mentions. Showdown will replace `{u}` with the username. Only applies if ghMentions option is enabled.
343+
* **ghMentionsLink**: (string) [default `https://github.com/{u}`] Changes the link generated by @mentions.
344+
Showdown will replace `{u}` with the username. Only applies if ghMentions option is enabled.
329345
Example: `@tivie` with ghMentionsOption set to `//mysite.com/{u}/profile` will result in `<a href="//mysite.com/tivie/profile">@tivie</a>`
330346

331347
* **encodeEmails**: (boolean) [default true] Enables e-mail addresses encoding through the use of Character Entities, transforming ASCII e-mail addresses into its equivalent decimal entities. (since v1.6.1)
332348

333349
NOTE: Prior to version 1.6.1, emails would always be obfuscated through dec and hex encoding.
334350

335-
* **openLinksInNewWindow**: (boolean) [default false] Open all links in new windows (by adding the attribute `target="_blank"` to `<a>` tags) **(since v1.7.0)**
351+
* **openLinksInNewWindow**: (boolean) [default false] Open all links in new windows
352+
(by adding the attribute `target="_blank"` to `<a>` tags) **(since v1.7.0)**
336353

337354
* **backslashEscapesHTMLTags**: (boolean) [default false] Support for HTML Tag escaping. ex: `\<div>foo\</div>` **(since v1.7.2)**
338355

@@ -409,15 +426,17 @@ var showdown = require('showdown'),
409426

410427
## Tests
411428

412-
A suite of tests is available which require node.js. Once node is installed, run the following command from the project root to install the dependencies:
429+
A suite of tests is available which require node.js. Once node is installed, run the following command from
430+
the project root to install the dependencies:
413431

414432
npm install
415433

416434
Once installed the tests can be run from the project root using:
417435

418436
npm test
419437

420-
New test cases can easily be added. Create a markdown file (ending in `.md`) which contains the markdown to test. Create a `.html` file of the exact same name. It will automatically be tested when the tests are executed with `mocha`.
438+
New test cases can easily be added. Create a markdown file (ending in `.md`) which contains the markdown to test.
439+
Create a `.html` file of the exact same name. It will automatically be tested when the tests are executed with `mocha`.
421440

422441
## Contributing
423442

dist/showdown.js

Lines changed: 21 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/showdown.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/showdown.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/showdown.min.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/options.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,14 @@ function getDefaultOpts (simple) {
1818
},
1919
prefixHeaderId: {
2020
defaultValue: false,
21-
describe: 'Specify a prefix to generated header ids',
21+
describe: 'Add a prefix to the generated header ids. Passing a string will prefix that string to the header id. Setting to true will add a generic \'section-\' prefix',
2222
type: 'string'
2323
},
24+
rawPrefixHeaderId: {
25+
defaultValue: false,
26+
describe: 'Setting this option to true will prevent showdown from modifying the prefix. This might result in malformed IDs (if, for instance, the " char is used in the prefix)',
27+
type: 'boolean'
28+
},
2429
ghCompatibleHeaderId: {
2530
defaultValue: false,
2631
describe: 'Generate header ids compatible with github style (spaces are replaced with dashes, a bunch of non alphanumeric chars are removed)',

src/subParsers/headers.js

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ showdown.subParser('headers', function (text, options, globals) {
5656
});
5757

5858
function headerId (m) {
59-
var title;
59+
var title,
60+
prefix;
6061

6162
// It is separate from other options to allow combining prefix and customized
6263
if (options.customizedHeaderId) {
@@ -66,13 +67,19 @@ showdown.subParser('headers', function (text, options, globals) {
6667
}
6768
}
6869

70+
title = m;
71+
6972
// Prefix id to prevent causing inadvertent pre-existing style matches.
7073
if (showdown.helper.isString(options.prefixHeaderId)) {
71-
title = options.prefixHeaderId + m;
74+
prefix = options.prefixHeaderId;
7275
} else if (options.prefixHeaderId === true) {
73-
title = 'section ' + m;
76+
prefix = 'section-';
7477
} else {
75-
title = m;
78+
prefix = '';
79+
}
80+
81+
if (!options.rawPrefixHeaderId) {
82+
title = prefix + title;
7683
}
7784

7885
if (options.ghCompatibleHeaderId) {
@@ -102,6 +109,10 @@ showdown.subParser('headers', function (text, options, globals) {
102109
.toLowerCase();
103110
}
104111

112+
if (options.rawPrefixHeaderId) {
113+
title = prefix + title;
114+
}
115+
105116
if (globals.hashLinkCounts[title]) {
106117
title = title + '-' + (globals.hashLinkCounts[title]++);
107118
} else {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<h1 id="/prefix/someheaderfoo">some header &amp;/) foo</h1>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# some header &/) foo

test/node/testsuite.features.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ var bootstrap = require('../bootstrap.js'),
99
simplifiedAutoLinkSuite = bootstrap.getTestSuite('test/features/simplifiedAutoLink/'),
1010
openLinksInNewWindowSuite = bootstrap.getTestSuite('test/features/openLinksInNewWindow/'),
1111
disableForced4SpacesIndentedSublistsSuite = bootstrap.getTestSuite('test/features/disableForced4SpacesIndentedSublists/'),
12-
html5CompatibleHeaderIdSuite = bootstrap.getTestSuite('test/features/rawHeaderId/');
12+
rawHeaderIdSuite = bootstrap.getTestSuite('test/features/rawHeaderId/'),
13+
rawPrefixHeaderIdSuite = bootstrap.getTestSuite('test/features/rawPrefixHeaderId/');
1314

1415
describe('makeHtml() features testsuite', function () {
1516
'use strict';
@@ -157,7 +158,7 @@ describe('makeHtml() features testsuite', function () {
157158
// test rawHeaderId support
158159
describe('rawHeaderId support', function () {
159160
var converter,
160-
suite = html5CompatibleHeaderIdSuite;
161+
suite = rawHeaderIdSuite;
161162
for (var i = 0; i < suite.length; ++i) {
162163
if (suite[i].name === 'with-prefixHeaderId') {
163164
converter = new showdown.Converter({rawHeaderId: true, prefixHeaderId: '/prefix/'});
@@ -167,4 +168,14 @@ describe('makeHtml() features testsuite', function () {
167168
it(suite[i].name.replace(/-/g, ' '), assertion(suite[i], converter));
168169
}
169170
});
171+
172+
// test rawPrefixHeaderId support
173+
describe('rawPrefixHeaderId support', function () {
174+
var converter,
175+
suite = rawPrefixHeaderIdSuite;
176+
for (var i = 0; i < suite.length; ++i) {
177+
converter = new showdown.Converter({rawPrefixHeaderId: true, prefixHeaderId: '/prefix/'});
178+
it(suite[i].name.replace(/-/g, ' '), assertion(suite[i], converter));
179+
}
180+
});
170181
});

0 commit comments

Comments
 (0)