mirror of
https://github.com/showdownjs/showdown.git
synced 2024-03-22 13:30:55 +08:00
improve commonmark compliance
This commit is contained in:
parent
7d2ede8dd9
commit
fb31f631e9
15
Gruntfile.js
15
Gruntfile.js
|
@ -2,6 +2,7 @@
|
||||||
* Created by Tivie on 12-11-2014.
|
* Created by Tivie on 12-11-2014.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const commonmark = require('commonmark-spec');
|
||||||
module.exports = function (grunt) {
|
module.exports = function (grunt) {
|
||||||
|
|
||||||
if (grunt.option('q') || grunt.option('quiet')) {
|
if (grunt.option('q') || grunt.option('quiet')) {
|
||||||
|
@ -230,6 +231,13 @@ module.exports = function (grunt) {
|
||||||
grunt.task.run(['lint', 'concat:test', 'mochaTest:single', 'clean']);
|
grunt.task.run(['lint', 'concat:test', 'mochaTest:single', 'clean']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
grunt.registerTask('extract-commonmark-tests', function () {
|
||||||
|
'use strict';
|
||||||
|
let commonmark = require('commonmark-spec');
|
||||||
|
let testsuite = JSON.stringify(commonmark.tests, null, 2);
|
||||||
|
grunt.file.write('test/functional/makehtml/cases/commonmark.testsuite.json', testsuite)
|
||||||
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tasks
|
* Tasks
|
||||||
*/
|
*/
|
||||||
|
@ -237,19 +245,14 @@ module.exports = function (grunt) {
|
||||||
grunt.registerTask('test-functional', ['concat:test', 'mochaTest:functional', 'clean']);
|
grunt.registerTask('test-functional', ['concat:test', 'mochaTest:functional', 'clean']);
|
||||||
grunt.registerTask('test-unit', ['concat:test', 'mochaTest:unit', 'clean']);
|
grunt.registerTask('test-unit', ['concat:test', 'mochaTest:unit', 'clean']);
|
||||||
grunt.registerTask('test-cli', ['clean', 'lint', 'concat:test', 'mochaTest:cli', 'clean']);
|
grunt.registerTask('test-cli', ['clean', 'lint', 'concat:test', 'mochaTest:cli', 'clean']);
|
||||||
grunt.registerTask('test-commonmark', ['clean', 'lint', 'concat:test', 'mochaTest:commonmark', 'clean']);
|
grunt.registerTask('test-commonmark', ['clean', 'lint', 'concat:test', 'extract-commonmark-tests', 'mochaTest:commonmark', 'clean']);
|
||||||
|
|
||||||
grunt.registerTask('performance', ['concat:test', 'performancejs', 'clean']);
|
grunt.registerTask('performance', ['concat:test', 'performancejs', 'clean']);
|
||||||
grunt.registerTask('build', ['test', 'concat:dist', 'concat:cli', 'uglify:dist', 'uglify:cli', 'endline']);
|
grunt.registerTask('build', ['test', 'concat:dist', 'concat:cli', 'uglify:dist', 'uglify:cli', 'endline']);
|
||||||
grunt.registerTask('build-without-test', ['concat:dist', 'uglify', 'endline']);
|
grunt.registerTask('build-without-test', ['concat:dist', 'uglify', 'endline']);
|
||||||
grunt.registerTask('prep-release', ['build', 'performance', 'generate-changelog']);
|
grunt.registerTask('prep-release', ['build', 'performance', 'generate-changelog']);
|
||||||
|
|
||||||
grunt.registerTask('extract-commonmark-tests', function () {
|
|
||||||
'use strict';
|
|
||||||
let commonmark = require('commonmark-spec');
|
|
||||||
|
|
||||||
grunt.file.write('test/functional/makehtml/cases/commonmark.testsuite.json', JSON.stringify(commonmark.tests, null, 2))
|
|
||||||
});
|
|
||||||
|
|
||||||
// Default task(s).
|
// Default task(s).
|
||||||
grunt.registerTask('default', ['test']);
|
grunt.registerTask('default', ['test']);
|
||||||
|
|
35
docs/spec-compliance.md
Normal file
35
docs/spec-compliance.md
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
# Spec Compliance
|
||||||
|
|
||||||
|
## Commonmark
|
||||||
|
|
||||||
|
Compliance percentage:
|
||||||
|
|
||||||
|
### How to enable commonmark flavor
|
||||||
|
|
||||||
|
Enable Commonmark flavor
|
||||||
|
|
||||||
|
```
|
||||||
|
let converter = new showdown.Converter();
|
||||||
|
converter.setFlavor('commonmark');
|
||||||
|
```
|
||||||
|
|
||||||
|
### Known differences:
|
||||||
|
|
||||||
|
#### ATX Headings
|
||||||
|
|
||||||
|
- Showdown doesn't support empty headings
|
||||||
|
|
||||||
|
Input:
|
||||||
|
```md
|
||||||
|
#
|
||||||
|
```
|
||||||
|
|
||||||
|
Showdown Output:
|
||||||
|
```html
|
||||||
|
<p>#</p>
|
||||||
|
```
|
||||||
|
|
||||||
|
Commonmark output:
|
||||||
|
```
|
||||||
|
<h1></h1>
|
||||||
|
```
|
13
package-lock.json
generated
13
package-lock.json
generated
|
@ -29,6 +29,7 @@
|
||||||
"grunt-endline": "^0.7.0",
|
"grunt-endline": "^0.7.0",
|
||||||
"grunt-eslint": "^24.0.0",
|
"grunt-eslint": "^24.0.0",
|
||||||
"grunt-mocha-test": "^0.13.3",
|
"grunt-mocha-test": "^0.13.3",
|
||||||
|
"html-prettify": "^1.0.6",
|
||||||
"karma": "^6.3.17",
|
"karma": "^6.3.17",
|
||||||
"karma-browserstack-launcher": "^1.6.0",
|
"karma-browserstack-launcher": "^1.6.0",
|
||||||
"karma-chai": "^0.1.0",
|
"karma-chai": "^0.1.0",
|
||||||
|
@ -3271,6 +3272,12 @@
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/html-prettify": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/html-prettify/-/html-prettify-1.0.6.tgz",
|
||||||
|
"integrity": "sha512-a2e5NX3pjP1io0Up0d3JOr+tMwKy8IsT4JaMMLznXzuuqPlthnvNdKd3lesQpu37/XWiA28FvDYQU0w/RlAymA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/htmlparser2": {
|
"node_modules/htmlparser2": {
|
||||||
"version": "3.8.3",
|
"version": "3.8.3",
|
||||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz",
|
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz",
|
||||||
|
@ -9249,6 +9256,12 @@
|
||||||
"whatwg-encoding": "^2.0.0"
|
"whatwg-encoding": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"html-prettify": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/html-prettify/-/html-prettify-1.0.6.tgz",
|
||||||
|
"integrity": "sha512-a2e5NX3pjP1io0Up0d3JOr+tMwKy8IsT4JaMMLznXzuuqPlthnvNdKd3lesQpu37/XWiA28FvDYQU0w/RlAymA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"htmlparser2": {
|
"htmlparser2": {
|
||||||
"version": "3.8.3",
|
"version": "3.8.3",
|
||||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz",
|
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz",
|
||||||
|
|
|
@ -60,6 +60,7 @@
|
||||||
"grunt-endline": "^0.7.0",
|
"grunt-endline": "^0.7.0",
|
||||||
"grunt-eslint": "^24.0.0",
|
"grunt-eslint": "^24.0.0",
|
||||||
"grunt-mocha-test": "^0.13.3",
|
"grunt-mocha-test": "^0.13.3",
|
||||||
|
"html-prettify": "^1.0.6",
|
||||||
"karma": "^6.3.17",
|
"karma": "^6.3.17",
|
||||||
"karma-browserstack-launcher": "^1.6.0",
|
"karma-browserstack-launcher": "^1.6.0",
|
||||||
"karma-chai": "^0.1.0",
|
"karma-chai": "^0.1.0",
|
||||||
|
|
|
@ -303,7 +303,8 @@ showdown.Converter = function (converterOptions) {
|
||||||
text = '\n\n' + text + '\n\n';
|
text = '\n\n' + text + '\n\n';
|
||||||
|
|
||||||
// detab
|
// detab
|
||||||
text = showdown.subParser('makehtml.detab')(text, options, globals);
|
//text = showdown.subParser('makehtml.detab')(text, options, globals);
|
||||||
|
text = showdown.helper.normalizeLeadingTabs(text);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Strip any lines consisting only of spaces and tabs.
|
* Strip any lines consisting only of spaces and tabs.
|
||||||
|
|
|
@ -705,6 +705,14 @@ showdown.helper._populateAttributes = function (attributes) {
|
||||||
return text;
|
return text;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
showdown.helper.normalizeLeadingTabs = function (text) {
|
||||||
|
// 1. (1 to 3 spaces followed by a tab at the start of the line) becomes (1 tab)
|
||||||
|
text = text.replace(/^ {1,3}\t/gm, '\t');
|
||||||
|
|
||||||
|
// 2.
|
||||||
|
return text;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove one level of line-leading tabs or spaces
|
* Remove one level of line-leading tabs or spaces
|
||||||
* @param {string} text
|
* @param {string} text
|
||||||
|
|
|
@ -30,21 +30,9 @@ var showdown = {},
|
||||||
noHeaderId: true,
|
noHeaderId: true,
|
||||||
ghCodeBlocks: false
|
ghCodeBlocks: false
|
||||||
},
|
},
|
||||||
ghost: {
|
commonmark: {
|
||||||
omitExtraWLInCodeBlocks: true,
|
noHeaderId: true,
|
||||||
parseImgDimensions: true,
|
requireSpaceBeforeHeadingText: true
|
||||||
simplifiedAutoLink: true,
|
|
||||||
literalMidWordUnderscores: true,
|
|
||||||
strikethrough: true,
|
|
||||||
tables: true,
|
|
||||||
tablesHeaderId: true,
|
|
||||||
ghCodeBlocks: true,
|
|
||||||
tasklists: true,
|
|
||||||
smoothLivePreview: true,
|
|
||||||
simpleLineBreaks: true,
|
|
||||||
requireSpaceBeforeHeadingText: true,
|
|
||||||
ghMentions: false,
|
|
||||||
encodeEmails: true
|
|
||||||
},
|
},
|
||||||
vanilla: getDefaultOpts(true),
|
vanilla: getDefaultOpts(true),
|
||||||
allOn: allOptionsOn()
|
allOn: allOptionsOn()
|
||||||
|
|
|
@ -23,7 +23,7 @@ showdown.subParser('makehtml.codeBlock', function (text, options, globals) {
|
||||||
// sentinel workarounds for lack of \A and \Z, safari\khtml bug
|
// sentinel workarounds for lack of \A and \Z, safari\khtml bug
|
||||||
text += '¨0';
|
text += '¨0';
|
||||||
|
|
||||||
let pattern = /(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=¨0))/g;
|
let pattern = /(?:\n\n|^)((?:(?: {4}|\t).*\n+)+)(\n* {0,3}[^ \t\n]|(?=¨0))/g;
|
||||||
text = text.replace(pattern, function (wholeMatch, m1, m2) {
|
text = text.replace(pattern, function (wholeMatch, m1, m2) {
|
||||||
let codeblock = m1,
|
let codeblock = m1,
|
||||||
nextChar = m2,
|
nextChar = m2,
|
||||||
|
@ -55,7 +55,7 @@ showdown.subParser('makehtml.codeBlock', function (text, options, globals) {
|
||||||
codeblock = captureStartEvent.matches.codeblock;
|
codeblock = captureStartEvent.matches.codeblock;
|
||||||
codeblock = showdown.helper.outdent(codeblock);
|
codeblock = showdown.helper.outdent(codeblock);
|
||||||
codeblock = showdown.subParser('makehtml.encodeCode')(codeblock, options, globals);
|
codeblock = showdown.subParser('makehtml.encodeCode')(codeblock, options, globals);
|
||||||
codeblock = showdown.subParser('makehtml.detab')(codeblock, options, globals);
|
//codeblock = showdown.subParser('makehtml.detab')(codeblock, options, globals);
|
||||||
codeblock = codeblock.replace(/^\n+/g, ''); // trim leading newlines
|
codeblock = codeblock.replace(/^\n+/g, ''); // trim leading newlines
|
||||||
codeblock = codeblock.replace(/\n+$/g, ''); // trim trailing newlines
|
codeblock = codeblock.replace(/\n+$/g, ''); // trim trailing newlines
|
||||||
attributes = captureStartEvent.attributes;
|
attributes = captureStartEvent.attributes;
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
showdown.subParser('makehtml.detab', function (text, options, globals) {
|
showdown.subParser('makehtml.detab', function (text, options, globals) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
return text;
|
||||||
let startEvent = new showdown.Event('makehtml.detab.onStart', text);
|
let startEvent = new showdown.Event('makehtml.detab.onStart', text);
|
||||||
startEvent
|
startEvent
|
||||||
.setOutput(text)
|
.setOutput(text)
|
||||||
|
|
|
@ -68,7 +68,7 @@ showdown.subParser('makehtml.githubCodeBlock', function (text, options, globals)
|
||||||
let lang = infostring.trim().split(' ')[0];
|
let lang = infostring.trim().split(' ')[0];
|
||||||
codeblock = captureStartEvent.matches.codeblock;
|
codeblock = captureStartEvent.matches.codeblock;
|
||||||
codeblock = showdown.subParser('makehtml.encodeCode')(codeblock, options, globals);
|
codeblock = showdown.subParser('makehtml.encodeCode')(codeblock, options, globals);
|
||||||
codeblock = showdown.subParser('makehtml.detab')(codeblock, options, globals);
|
//codeblock = showdown.subParser('makehtml.detab')(codeblock, options, globals);
|
||||||
codeblock = codeblock
|
codeblock = codeblock
|
||||||
.replace(/^\n+/g, '') // trim leading newlines
|
.replace(/^\n+/g, '') // trim leading newlines
|
||||||
.replace(/\n+$/g, ''); // trim trailing whitespace
|
.replace(/\n+$/g, ''); // trim trailing whitespace
|
||||||
|
|
|
@ -73,16 +73,18 @@ showdown.subParser('makehtml.heading', function (text, options, globals) {
|
||||||
startEvent = globals.converter.dispatch(startEvent);
|
startEvent = globals.converter.dispatch(startEvent);
|
||||||
text = startEvent.output;
|
text = startEvent.output;
|
||||||
|
|
||||||
let setextRegexH1 = (options.smoothLivePreview) ? /^(.+)[ \t]*\n={2,}[ \t]*\n+/gm : /^(.+)[ \t]*\n=+[ \t]*\n+/gm,
|
let setextRegexH1 = (options.smoothLivePreview) ? /^(.+[ \t]*\n)(.+[ \t]*\n)?(.+[ \t]*\n)?={2,}[ \t]*\n+/gm : /^( {0,3}[^ \t\n].+[ \t]*\n)(.+[ \t]*\n)?(.+[ \t]*\n)? {0,3}=+[ \t]*$/gm,
|
||||||
setextRegexH2 = (options.smoothLivePreview) ? /^(.+)[ \t]*\n-{2,}[ \t]*\n+/gm : /^(.+)[ \t]*\n-+[ \t]*\n+/gm,
|
setextRegexH2 = (options.smoothLivePreview) ? /^(.+[ \t]*\n)(.+[ \t]*\n)?(.+[ \t]*\n)?-{2,}[ \t]*\n+/gm : /^( {0,3}[^ \t\n].+[ \t]*\n)(.+[ \t]*\n)?(.+[ \t]*\n)? {0,3}-+[ \t]*$/gm,
|
||||||
atxRegex = (options.requireSpaceBeforeHeadingText) ? /^(#{1,6})[ \t]+(.+?)[ \t]*#*\n+/gm : /^(#{1,6})[ \t]*(.+?)[ \t]*#*\n+/gm;
|
atxRegex = (options.requireSpaceBeforeHeadingText) ? /^ {0,3}(#{1,6})[ \t]+(.+?)(?:[ \t]+#+)?[ \t]*$/gm : /^ {0,3}(#{1,6})[ \t]*(.+?)[ \t]*#*[ \t]*$/gm;
|
||||||
|
|
||||||
text = text.replace(setextRegexH1, function (wholeMatch, headingText) {
|
text = text.replace(setextRegexH1, function (wholeMatch, line1, line2, line3) {
|
||||||
|
let headingText = line1.trim() + ((line2) ? '\n' + line2.trim() : '') + ((line3) ? '\n' + line3.trim() : '');
|
||||||
let id = (options.noHeaderId) ? null : showdown.subParser('makehtml.heading.id')(headingText, options, globals);
|
let id = (options.noHeaderId) ? null : showdown.subParser('makehtml.heading.id')(headingText, options, globals);
|
||||||
return parseHeader(setextRegexH1, wholeMatch, headingText, options.headerLevelStart, id);
|
return parseHeader(setextRegexH1, wholeMatch, headingText, options.headerLevelStart, id);
|
||||||
});
|
});
|
||||||
|
|
||||||
text = text.replace(setextRegexH2, function (wholeMatch, headingText) {
|
text = text.replace(setextRegexH2, function (wholeMatch, line1, line2, line3) {
|
||||||
|
let headingText = line1.trim() + ((line2) ? '\n' + line2.trim() : '') + ((line3) ? '\n' + line3.trim() : '');
|
||||||
let id = (options.noHeaderId) ? null : showdown.subParser('makehtml.heading.id')(headingText, options, globals);
|
let id = (options.noHeaderId) ? null : showdown.subParser('makehtml.heading.id')(headingText, options, globals);
|
||||||
return parseHeader(setextRegexH2, wholeMatch, headingText, options.headerLevelStart + 1, id);
|
return parseHeader(setextRegexH2, wholeMatch, headingText, options.headerLevelStart + 1, id);
|
||||||
});
|
});
|
||||||
|
@ -154,7 +156,7 @@ showdown.subParser('makehtml.heading.id', function (m, options, globals) {
|
||||||
.toLowerCase();
|
.toLowerCase();
|
||||||
} else {
|
} else {
|
||||||
title = title
|
title = title
|
||||||
.replace(/[^\w]/g, '')
|
.replace(/\W/g, '')
|
||||||
.toLowerCase();
|
.toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ showdown.subParser('makehtml.paragraphs', function (text, options, globals) {
|
||||||
for (var i = 0; i < end; i++) {
|
for (var i = 0; i < end; i++) {
|
||||||
var str = grafs[i];
|
var str = grafs[i];
|
||||||
// if this is an HTML marker, copy it
|
// if this is an HTML marker, copy it
|
||||||
if (str.search(/¨(K|G)(\d+)\1/g) >= 0) {
|
if (str.search(/¨([KG])(\d+)\1/g) >= 0) {
|
||||||
grafsOut.push(str);
|
grafsOut.push(str);
|
||||||
|
|
||||||
// test for presence of characters to prevent empty lines being parsed
|
// test for presence of characters to prevent empty lines being parsed
|
||||||
|
|
|
@ -104,11 +104,11 @@ ___triple underscores___
|
||||||
<h6 id="heading6markupheading6">Heading 6 markup <code>###### Heading 6</code></h6>
|
<h6 id="heading6markupheading6">Heading 6 markup <code>###### Heading 6</code></h6>
|
||||||
<h6 id="-5"> </h6>
|
<h6 id="-5"> </h6>
|
||||||
<p>You can also create Setext-style headings which have two levels.</p>
|
<p>You can also create Setext-style headings which have two levels.</p>
|
||||||
<h1 id="level1markupuseanequalsignequalsign">Level 1 markup use an equal sign = (equal sign) </h1>
|
<h1 id="level1markupuseanequalsignequalsign">Level 1 markup use an equal sign = (equal sign)</h1>
|
||||||
<pre><code> Level 1 markup use an equal sign = (equal sign)
|
<pre><code> Level 1 markup use an equal sign = (equal sign)
|
||||||
==============================
|
==============================
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<h2 id="level2markupusesdashes">Level 2 markup uses - (dashes) </h2>
|
<h2 id="level2markupusesdashes">Level 2 markup uses - (dashes)</h2>
|
||||||
<pre><code>Level 2 markup uses - (dashes)
|
<pre><code>Level 2 markup uses - (dashes)
|
||||||
-------------
|
-------------
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
<p># This is an H1</p>
|
<h1>This is an H1</h1>
|
|
@ -1 +1 @@
|
||||||
<p>This is a paragraph with 1 trailing tab. </p>
|
<p>This is a paragraph with 1 trailing tab. </p>
|
|
@ -3,19 +3,35 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// jshint ignore: start
|
// jshint ignore: start
|
||||||
var bootstrap = require('./makehtml.bootstrap.js'),
|
let bootstrap = require('./makehtml.bootstrap.js'),
|
||||||
converter = new bootstrap.showdown.Converter(),
|
converter = new bootstrap.showdown.Converter({
|
||||||
|
noHeaderId: true,
|
||||||
|
requireSpaceBeforeHeadingText: true
|
||||||
|
}),
|
||||||
assertion = bootstrap.assertion,
|
assertion = bootstrap.assertion,
|
||||||
testsuite = bootstrap.getJsonTestSuite('test/functional/makehtml/cases/commonmark.testsuite.json');
|
testsuite = bootstrap.getJsonTestSuite('test/functional/makehtml/cases/commonmark.testsuite.json');
|
||||||
|
|
||||||
describe('makeHtml() commonmark testsuite', function () {
|
describe('makeHtml() commonmark testsuite', function () {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
for (var section in testsuite) {
|
for (let section in testsuite) {
|
||||||
if (testsuite.hasOwnProperty(section)) {
|
if (testsuite.hasOwnProperty(section)) {
|
||||||
describe(section, function () {
|
describe(section, function () {
|
||||||
for (var i = 0; i < testsuite[section].length; ++i) {
|
for (let i = 0; i < testsuite[section].length; ++i) {
|
||||||
it(testsuite[section][i].name, assertion(testsuite[section][i], converter));
|
let name = testsuite[section][i].name;
|
||||||
|
switch (name) {
|
||||||
|
case 'ATX headings_79': // empty headings don't make sense
|
||||||
|
case 'Setext headings_92': // lazy continuation is needed for compatibility
|
||||||
|
case 'Setext headings_93': // lazy continuation is needed for compatibility
|
||||||
|
case 'Setext headings_94': // lazy continuation is needed for compatibility
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (testsuite[section][i].name === 'ATX headings_79') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
it(name, assertion(testsuite[section][i], converter, true));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
require('source-map-support').install();
|
require('source-map-support').install();
|
||||||
require('chai').should();
|
require('chai').should();
|
||||||
|
const htmlPrettify = require('html-prettify');
|
||||||
let fs = require('fs');
|
let fs = require('fs');
|
||||||
|
|
||||||
function getTestSuite (dir) {
|
function getTestSuite (dir) {
|
||||||
|
@ -52,7 +53,13 @@
|
||||||
let section = jsonArray[i].section;
|
let section = jsonArray[i].section;
|
||||||
let name = jsonArray[i].section + '_' + (jsonArray[i].example || jsonArray[i].number);
|
let name = jsonArray[i].section + '_' + (jsonArray[i].example || jsonArray[i].number);
|
||||||
let md = jsonArray[i].markdown;
|
let md = jsonArray[i].markdown;
|
||||||
|
// transformations
|
||||||
|
md = md.replace(/→/g, '\t'); // replace → with tabs
|
||||||
|
|
||||||
let html = jsonArray[i].html;
|
let html = jsonArray[i].html;
|
||||||
|
// transformations
|
||||||
|
html = html.replace(/→/g, '\t'); // replace → with tabs
|
||||||
|
|
||||||
if (!tcObj.hasOwnProperty(section)) {
|
if (!tcObj.hasOwnProperty(section)) {
|
||||||
tcObj[section] = [];
|
tcObj[section] = [];
|
||||||
}
|
}
|
||||||
|
@ -67,10 +74,15 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function assertion (testCase, converter) {
|
function assertion (testCase, converter, prettify) {
|
||||||
|
prettify = prettify || false;
|
||||||
return function () {
|
return function () {
|
||||||
testCase.actual = converter.makeHtml(testCase.input);
|
testCase.actual = converter.makeHtml(testCase.input);
|
||||||
testCase = normalize(testCase);
|
// transformations for readability
|
||||||
|
//testCase.expected = testCase.expected.replace(/\t/g, '→');
|
||||||
|
//testCase.actual = testCase.actual.replace(/\t/g, '→');
|
||||||
|
|
||||||
|
testCase = normalize(testCase, prettify);
|
||||||
|
|
||||||
// Compare
|
// Compare
|
||||||
testCase.actual.should.equal(testCase.expected, testCase.file);
|
testCase.actual.should.equal(testCase.expected, testCase.file);
|
||||||
|
@ -78,7 +90,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
//Normalize input/output
|
//Normalize input/output
|
||||||
function normalize (testCase) {
|
function normalize (testCase, prettify) {
|
||||||
|
|
||||||
// Normalize line returns
|
// Normalize line returns
|
||||||
testCase.expected = testCase.expected.replace(/(\r\n)|\n|\r/g, '\n');
|
testCase.expected = testCase.expected.replace(/(\r\n)|\n|\r/g, '\n');
|
||||||
|
@ -96,9 +108,12 @@
|
||||||
testCase.expected = testCase.expected.trim();
|
testCase.expected = testCase.expected.trim();
|
||||||
testCase.actual = testCase.actual.trim();
|
testCase.actual = testCase.actual.trim();
|
||||||
|
|
||||||
//Beautify
|
//prettify
|
||||||
//testCase.expected = beautify(testCase.expected, beauOptions);
|
if (prettify) {
|
||||||
//testCase.actual = beautify(testCase.actual, beauOptions);
|
testCase.expected = htmlPrettify(testCase.expected);
|
||||||
|
testCase.actual = htmlPrettify(testCase.actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Normalize line returns
|
// Normalize line returns
|
||||||
testCase.expected = testCase.expected.replace(/(\r\n)|\n|\r/g, '\n');
|
testCase.expected = testCase.expected.replace(/(\r\n)|\n|\r/g, '\n');
|
||||||
|
|
Loading…
Reference in New Issue
Block a user