mirror of https://github.com/showdownjs/showdown
feat(ghCompatibleHeaderId): generate header ids compatible with github
style Github replaces spaces with dashes and removes a bunch of characters from generated header ids ][&~$!@#*()=:/,;?+'.\ This feature implements this. Closes # 320, closes #321pull/336/head
parent
08846c4519
commit
db97a90d5b
|
@ -189,6 +189,8 @@ var defaultOptions = showdown.getDefaultOptions();
|
|||
|
||||
* **noHeaderId**: (boolean) [default false] Disable the automatic generation of header ids. Setting to true overrides **prefixHeaderId**
|
||||
|
||||
* **ghCompatibleHeaderId**: (boolean) [default false] Generate header ids compatible with github style (spaces are replaced with dashes, ][&~$!@#*()=:/,;?+'.\ chars are removed
|
||||
|
||||
* **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.
|
||||
|
||||
* **parseImgDimensions**: (boolean) [default false] Enable support for setting image dimensions from within markdown syntax.
|
||||
|
|
|
@ -23,6 +23,11 @@ function getDefaultOpts(simple) {
|
|||
describe: 'Specify a prefix to generated header ids',
|
||||
type: 'string'
|
||||
},
|
||||
ghCompatibleHeaderId: {
|
||||
defaultValue: false,
|
||||
describe: 'Generate header ids compatible with github style (spaces are replaced with dashes, &~$!@#*()=:/,;?+\'. chars are removed)',
|
||||
type: 'string'
|
||||
},
|
||||
headerLevelStart: {
|
||||
defaultValue: false,
|
||||
describe: 'The header blocks level start',
|
||||
|
@ -146,7 +151,8 @@ var showdown = {},
|
|||
tasklists: true,
|
||||
disableForced4SpacesIndentedSublists: true,
|
||||
simpleLineBreaks: true,
|
||||
requireSpaceBeforeHeadingText: true
|
||||
requireSpaceBeforeHeadingText: true,
|
||||
ghCompatibleHeaderId: true
|
||||
},
|
||||
vanilla: getDefaultOpts(true),
|
||||
allOn: allOptionsOn()
|
||||
|
@ -1786,6 +1792,7 @@ showdown.subParser('headers', function (text, options, globals) {
|
|||
|
||||
var prefixHeader = options.prefixHeaderId,
|
||||
headerLevelStart = (isNaN(parseInt(options.headerLevelStart))) ? 1 : parseInt(options.headerLevelStart),
|
||||
ghHeaderId = options.ghCompatibleHeaderId,
|
||||
|
||||
// Set text-style headers:
|
||||
// Header 1
|
||||
|
@ -1833,7 +1840,21 @@ showdown.subParser('headers', function (text, options, globals) {
|
|||
});
|
||||
|
||||
function headerId(m) {
|
||||
var title, escapedId = m.replace(/[^\w]/g, '').toLowerCase();
|
||||
var title, escapedId;
|
||||
|
||||
if (ghHeaderId) {
|
||||
escapedId = m
|
||||
.replace(/ /g, '-')
|
||||
//replace previously escaped chars (&, ~ and $)
|
||||
.replace(/&/g, '')
|
||||
.replace(/~T/g, '')
|
||||
.replace(/~D/g, '')
|
||||
//replace rest of the chars (&~$ are repeated as they might have been escaped)
|
||||
.replace(/[&~$!@#*()=:/,;?+'.\\]/g, '')
|
||||
.toLowerCase();
|
||||
} else {
|
||||
escapedId = m.replace(/[^\w]/g, '').toLowerCase();
|
||||
}
|
||||
|
||||
if (globals.hashLinkCounts[escapedId]) {
|
||||
title = escapedId + '-' + (globals.hashLinkCounts[escapedId]++);
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1 +1 @@
|
|||
{"1.5.5":[{"suiteName":"Basic","cycles":100,"tests":[{"name":"Simple \"Hello World\"","time":0.31472779000000006,"maxTime":5.7157219999999995,"minTime":0.1630309999999966},{"name":"readme.md","time":8.35187898,"maxTime":18.016863999999998,"minTime":7.207408999999984}]},{"suiteName":"subParsers","cycles":1000,"tests":[{"name":"hashHTMLBlocks","time":0.673032811000001,"maxTime":1.1442289999999957,"minTime":0.6216859999999542},{"name":"anchors","time":0.17780483999999888,"maxTime":0.5279669999999896,"minTime":0.15700300000003153},{"name":"autoLinks","time":0.014361767000001236,"maxTime":0.19256300000006377,"minTime":0.012655999999878986},{"name":"blockGamut","time":7.3270934659999964,"maxTime":16.04994700000134,"minTime":6.464278000000377},{"name":"blockQuotes","time":0.06438723300000856,"maxTime":0.2558470000003581,"minTime":0.05816000000049826},{"name":"codeBlocks","time":0.07155547099998148,"maxTime":1.5896259999990434,"minTime":0.05936599999949976},{"name":"codeSpans","time":0.1839475929999935,"maxTime":1.4350329999997484,"minTime":0.16453699999874516},{"name":"detab","time":0.024342816999995194,"maxTime":0.19678200000089419,"minTime":0.02199799999834795},{"name":"encodeAmpsAndAngles","time":0.016193075999983195,"maxTime":0.35378599999967264,"minTime":0.013559999999415595},{"name":"encodeBackslashEscapes","time":0.01439162099999885,"maxTime":0.23565699999926437,"minTime":0.012354999998933636},{"name":"encodeCode","time":0.16650568799998655,"maxTime":0.48909199999980046,"minTime":0.1485659999998461},{"name":"encodeEmailAddress","time":2.2962369480000233,"maxTime":3.975118999998813,"minTime":2.079321000001073},{"name":"escapeSpecialCharsWithinTagAttributes","time":0.06015714999998454,"maxTime":0.41375499999958265,"minTime":0.05303699999967648},{"name":"githubCodeBlocks","time":0.07636622499999976,"maxTime":4.3967090000005555,"minTime":0.05514699999912409},{"name":"hashBlock","time":0.023663276999977823,"maxTime":5.066611999998713,"minTime":0.010847999999896274},{"name":"hashElement","time":0.0007292739999957121,"maxTime":0.23927300000104879,"minTime":0},{"name":"hashHTMLSpans","time":0.031071996999991826,"maxTime":3.5767329999998765,"minTime":0.010245999999824562},{"name":"hashPreCodeTags","time":0.018975442000006296,"maxTime":0.3323899999995774,"minTime":0.014765999998417101},{"name":"headers","time":0.45554695500000525,"maxTime":2.677201000000423,"minTime":0.3911530000004859},{"name":"images","time":0.04111330700001417,"maxTime":1.6565260000006674,"minTime":0.0322439999999915},{"name":"italicsAndBold","time":0.038311039999998686,"maxTime":0.2980360000001383,"minTime":0.03465499999947497},{"name":"lists","time":5.024616153999989,"maxTime":9.631475000000137,"minTime":4.572998999999982},{"name":"outdent","time":0.0506727579999897,"maxTime":0.5855249999985972,"minTime":0.04369599999699858},{"name":"paragraphs","time":1.3435436269999992,"maxTime":2.651585999999952,"minTime":1.1951570000019274},{"name":"spanGamut","time":0.6120240349999804,"maxTime":1.057440000000497,"minTime":0.5553889999973762},{"name":"strikethrough","time":0.00045323800000551275,"maxTime":0.22752000000036787,"minTime":0},{"name":"stripBlankLines","time":0.03007630300002711,"maxTime":0.29351499999756925,"minTime":0.02681999999913387},{"name":"stripLinkDefinitions","time":0.06855551200000627,"maxTime":0.4496159999980591,"minTime":0.06026999999812688},{"name":"tables","time":0.0008534279999839782,"maxTime":0.2046169999994163,"minTime":0},{"name":"unescapeSpecialChars","time":0.0035457099999912315,"maxTime":0.1681540000026871,"minTime":0.0027119999977003317}]}],"1.5.4":[{"suiteName":"Basic","cycles":100,"tests":[{"name":"Simple \"Hello World\"","time":0.30990324000000025,"maxTime":5.549075,"minTime":0.14916800000000308},{"name":"readme.md","time":8.072704459999997,"maxTime":17.975579000000003,"minTime":7.220064999999977}]}]}
|
||||
{"1.5.5":[{"suiteName":"Basic","cycles":100,"tests":[{"name":"Simple \"Hello World\"","time":0.6435890300000008,"maxTime":13.067478000000001,"minTime":0.17839999999999634},{"name":"readme.md","time":8.181142640000001,"maxTime":26.315163000000013,"minTime":7.018763000000035}]},{"suiteName":"subParsers","cycles":1000,"tests":[{"name":"hashHTMLBlocks","time":0.6653926609999921,"maxTime":1.1002320000000054,"minTime":0.6201799999998912},{"name":"anchors","time":0.18655217499999913,"maxTime":0.5605129999999008,"minTime":0.16122199999995246},{"name":"autoLinks","time":0.015408060000002478,"maxTime":0.19828899999993155,"minTime":0.013559999999870342},{"name":"blockGamut","time":7.104302655000017,"maxTime":15.671752000000197,"minTime":6.344039000000521},{"name":"blockQuotes","time":0.06466147199998705,"maxTime":0.22782099999858474,"minTime":0.05815999999867927},{"name":"codeBlocks","time":0.07110766699999113,"maxTime":1.0583440000009432,"minTime":0.06057099999998172},{"name":"codeSpans","time":0.18858266200001708,"maxTime":1.0360440000004019,"minTime":0.1681540000008681},{"name":"detab","time":0.02511971000000085,"maxTime":0.25132699999994657,"minTime":0.02199800000016694},{"name":"encodeAmpsAndAngles","time":0.01657520100001966,"maxTime":0.2675989999988815,"minTime":0.01356099999975413},{"name":"encodeBackslashEscapes","time":0.013978774000006524,"maxTime":0.2570529999993596,"minTime":0.012354999998933636},{"name":"encodeCode","time":0.17534642000000894,"maxTime":0.6436849999990955,"minTime":0.1494700000002922},{"name":"encodeEmailAddress","time":2.291462927999999,"maxTime":3.8542770000003657,"minTime":2.071786999998949},{"name":"escapeSpecialCharsWithinTagAttributes","time":0.059004508000005444,"maxTime":0.43816399999923306,"minTime":0.05303699999967648},{"name":"githubCodeBlocks","time":0.08072707700000319,"maxTime":4.627243000000817,"minTime":0.05635199999960605},{"name":"hashBlock","time":0.0287458620000034,"maxTime":5.0681189999995695,"minTime":0.011149999998451676},{"name":"hashElement","time":0.0006084250000003522,"maxTime":0.1970839999994496,"minTime":0},{"name":"hashHTMLSpans","time":0.023783199999992576,"maxTime":3.8319769999998243,"minTime":0.010245000001305016},{"name":"hashPreCodeTags","time":0.017276158000002397,"maxTime":0.41375499999958265,"minTime":0.014463999999861699},{"name":"headers","time":0.4617156479999994,"maxTime":2.67147500000101,"minTime":0.3932629999999335},{"name":"images","time":0.039165076999997835,"maxTime":0.7331869999998162,"minTime":0.032545999998546904},{"name":"italicsAndBold","time":0.037845750000002225,"maxTime":0.3085829999999987,"minTime":0.03435399999943911},{"name":"lists","time":4.972232302000022,"maxTime":11.410649999999805,"minTime":4.442514999998821},{"name":"outdent","time":0.049343790000006264,"maxTime":0.536404999998922,"minTime":0.04369600000063656},{"name":"paragraphs","time":1.3606319900000234,"maxTime":2.980360000001383,"minTime":1.2026909999985946},{"name":"spanGamut","time":0.629801320999999,"maxTime":1.2726049999982934,"minTime":0.5505679999987478},{"name":"strikethrough","time":0.00038121299999693294,"maxTime":0.2079330000015034,"minTime":0},{"name":"stripBlankLines","time":0.030241460999983247,"maxTime":0.27091400000063004,"minTime":0.02681999999913387},{"name":"stripLinkDefinitions","time":0.06758093699999518,"maxTime":0.3387189999994007,"minTime":0.06087200000183657},{"name":"tables","time":0.0005864269999910903,"maxTime":0.18593300000065938,"minTime":0},{"name":"unescapeSpecialChars","time":0.003310937999998714,"maxTime":0.21094599999923958,"minTime":0.0027119999977003317}]}],"1.5.4":[{"suiteName":"Basic","cycles":100,"tests":[{"name":"Simple \"Hello World\"","time":0.30990324000000025,"maxTime":5.549075,"minTime":0.14916800000000308},{"name":"readme.md","time":8.072704459999997,"maxTime":17.975579000000003,"minTime":7.220064999999977}]}]}
|
|
@ -6,42 +6,42 @@
|
|||
### Test Suite: Basic (100 cycles)
|
||||
| test | avgTime | max | min |
|
||||
|:-----|--------:|----:|----:|
|
||||
|Simple "Hello World"|0.315|5.716|0.163|
|
||||
|readme.md|8.352|18.017|7.207|
|
||||
|Simple "Hello World"|0.644|13.067|0.178|
|
||||
|readme.md|8.181|26.315|7.019|
|
||||
|
||||
### Test Suite: subParsers (1000 cycles)
|
||||
| test | avgTime | max | min |
|
||||
|:-----|--------:|----:|----:|
|
||||
|hashHTMLBlocks|0.673|1.144|0.622|
|
||||
|anchors|0.178|0.528|0.157|
|
||||
|autoLinks|0.014|0.193|0.013|
|
||||
|blockGamut|7.327|16.050|6.464|
|
||||
|blockQuotes|0.064|0.256|0.058|
|
||||
|codeBlocks|0.072|1.590|0.059|
|
||||
|codeSpans|0.184|1.435|0.165|
|
||||
|detab|0.024|0.197|0.022|
|
||||
|encodeAmpsAndAngles|0.016|0.354|0.014|
|
||||
|encodeBackslashEscapes|0.014|0.236|0.012|
|
||||
|encodeCode|0.167|0.489|0.149|
|
||||
|encodeEmailAddress|2.296|3.975|2.079|
|
||||
|escapeSpecialCharsWithinTagAttributes|0.060|0.414|0.053|
|
||||
|githubCodeBlocks|0.076|4.397|0.055|
|
||||
|hashBlock|0.024|5.067|0.011|
|
||||
|hashElement|0.001|0.239|0.000|
|
||||
|hashHTMLSpans|0.031|3.577|0.010|
|
||||
|hashPreCodeTags|0.019|0.332|0.015|
|
||||
|headers|0.456|2.677|0.391|
|
||||
|images|0.041|1.657|0.032|
|
||||
|italicsAndBold|0.038|0.298|0.035|
|
||||
|lists|5.025|9.631|4.573|
|
||||
|outdent|0.051|0.586|0.044|
|
||||
|paragraphs|1.344|2.652|1.195|
|
||||
|spanGamut|0.612|1.057|0.555|
|
||||
|strikethrough|0.000|0.228|0.000|
|
||||
|stripBlankLines|0.030|0.294|0.027|
|
||||
|stripLinkDefinitions|0.069|0.450|0.060|
|
||||
|tables|0.001|0.205|0.000|
|
||||
|unescapeSpecialChars|0.004|0.168|0.003|
|
||||
|hashHTMLBlocks|0.665|1.100|0.620|
|
||||
|anchors|0.187|0.561|0.161|
|
||||
|autoLinks|0.015|0.198|0.014|
|
||||
|blockGamut|7.104|15.672|6.344|
|
||||
|blockQuotes|0.065|0.228|0.058|
|
||||
|codeBlocks|0.071|1.058|0.061|
|
||||
|codeSpans|0.189|1.036|0.168|
|
||||
|detab|0.025|0.251|0.022|
|
||||
|encodeAmpsAndAngles|0.017|0.268|0.014|
|
||||
|encodeBackslashEscapes|0.014|0.257|0.012|
|
||||
|encodeCode|0.175|0.644|0.149|
|
||||
|encodeEmailAddress|2.291|3.854|2.072|
|
||||
|escapeSpecialCharsWithinTagAttributes|0.059|0.438|0.053|
|
||||
|githubCodeBlocks|0.081|4.627|0.056|
|
||||
|hashBlock|0.029|5.068|0.011|
|
||||
|hashElement|0.001|0.197|0.000|
|
||||
|hashHTMLSpans|0.024|3.832|0.010|
|
||||
|hashPreCodeTags|0.017|0.414|0.014|
|
||||
|headers|0.462|2.671|0.393|
|
||||
|images|0.039|0.733|0.033|
|
||||
|italicsAndBold|0.038|0.309|0.034|
|
||||
|lists|4.972|11.411|4.443|
|
||||
|outdent|0.049|0.536|0.044|
|
||||
|paragraphs|1.361|2.980|1.203|
|
||||
|spanGamut|0.630|1.273|0.551|
|
||||
|strikethrough|0.000|0.208|0.000|
|
||||
|stripBlankLines|0.030|0.271|0.027|
|
||||
|stripLinkDefinitions|0.068|0.339|0.061|
|
||||
|tables|0.001|0.186|0.000|
|
||||
|unescapeSpecialChars|0.003|0.211|0.003|
|
||||
|
||||
|
||||
## [version 1.5.4](https://github.com/showdownjs/showdown/tree/)
|
||||
|
|
|
@ -21,6 +21,11 @@ function getDefaultOpts(simple) {
|
|||
describe: 'Specify a prefix to generated header ids',
|
||||
type: 'string'
|
||||
},
|
||||
ghCompatibleHeaderId: {
|
||||
defaultValue: false,
|
||||
describe: 'Generate header ids compatible with github style (spaces are replaced with dashes, &~$!@#*()=:/,;?+\'. chars are removed)',
|
||||
type: 'string'
|
||||
},
|
||||
headerLevelStart: {
|
||||
defaultValue: false,
|
||||
describe: 'The header blocks level start',
|
||||
|
|
|
@ -21,7 +21,8 @@ var showdown = {},
|
|||
tasklists: true,
|
||||
disableForced4SpacesIndentedSublists: true,
|
||||
simpleLineBreaks: true,
|
||||
requireSpaceBeforeHeadingText: true
|
||||
requireSpaceBeforeHeadingText: true,
|
||||
ghCompatibleHeaderId: true
|
||||
},
|
||||
vanilla: getDefaultOpts(true),
|
||||
allOn: allOptionsOn()
|
||||
|
|
|
@ -5,6 +5,7 @@ showdown.subParser('headers', function (text, options, globals) {
|
|||
|
||||
var prefixHeader = options.prefixHeaderId,
|
||||
headerLevelStart = (isNaN(parseInt(options.headerLevelStart))) ? 1 : parseInt(options.headerLevelStart),
|
||||
ghHeaderId = options.ghCompatibleHeaderId,
|
||||
|
||||
// Set text-style headers:
|
||||
// Header 1
|
||||
|
@ -52,7 +53,21 @@ showdown.subParser('headers', function (text, options, globals) {
|
|||
});
|
||||
|
||||
function headerId(m) {
|
||||
var title, escapedId = m.replace(/[^\w]/g, '').toLowerCase();
|
||||
var title, escapedId;
|
||||
|
||||
if (ghHeaderId) {
|
||||
escapedId = m
|
||||
.replace(/ /g, '-')
|
||||
//replace previously escaped chars (&, ~ and $)
|
||||
.replace(/&/g, '')
|
||||
.replace(/~T/g, '')
|
||||
.replace(/~D/g, '')
|
||||
//replace rest of the chars (&~$ are repeated as they might have been escaped)
|
||||
.replace(/[&~$!@#*()=:/,;?+'.\\]/g, '')
|
||||
.toLowerCase();
|
||||
} else {
|
||||
escapedId = m.replace(/[^\w]/g, '').toLowerCase();
|
||||
}
|
||||
|
||||
if (globals.hashLinkCounts[escapedId]) {
|
||||
title = escapedId + '-' + (globals.hashLinkCounts[escapedId]++);
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
<h1 id="some-header">some header</h1>
|
||||
<h1 id="some-header-with--chars">some header with ~!@#$&*()=:/,;?+'.\ chars</h1>
|
|
@ -0,0 +1,3 @@
|
|||
# some header
|
||||
|
||||
# some header with ~!@#$&*()=:/,;?+'.\ chars
|
|
@ -43,6 +43,8 @@ describe('makeHtml() features testsuite', function () {
|
|||
converter = new showdown.Converter({simplifiedAutoLink: true, excludeTrailingPunctuationFromURLs: true});
|
||||
} else if (testsuite[i].name === 'requireSpaceBeforeHeadingText') {
|
||||
converter = new showdown.Converter({requireSpaceBeforeHeadingText: true});
|
||||
} else if (testsuite[i].name === '#320.github-compatible-generated-header-id') {
|
||||
converter = new showdown.Converter({ghCompatibleHeaderId: true});
|
||||
} else {
|
||||
converter = new showdown.Converter();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue