fix(cli): cli now works properly

The CLI was completely rewrote. Changed dependency from yargs to
commanderjs,
which is cleaner, faster and has no dependencies.
Also added a complete testsuite for the cli.

Merged branch 'cli_refactor' into develop

Closes #893, #894
pull/896/head
Estevao Soares dos Santos 2022-03-03 12:15:50 +00:00
parent bd093ab493
commit c3411a567d
21 changed files with 918 additions and 1221 deletions

View File

@ -13,12 +13,12 @@ module.exports = function (grunt) {
pkg: grunt.file.readJSON('package.json'),
concat: {
options: {
sourceMap: true,
banner: ';/*! <%= pkg.name %> v <%= pkg.version %> - <%= grunt.template.today("dd-mm-yyyy") %> */\n(function(){\n',
footer: '}).call(this);\n'
},
dist: {
options: {
sourceMap: true,
banner: ';/*! <%= pkg.name %> v <%= pkg.version %> - <%= grunt.template.today("dd-mm-yyyy") %> */\n(function(){\n',
footer: '}).call(this);\n'
},
src: [
'src/options.js',
'src/showdown.js',
@ -30,6 +30,12 @@ module.exports = function (grunt) {
],
dest: 'dist/<%= pkg.name %>.js'
},
cli: {
src: [
'src/cli/cli.js'
],
dest: 'bin/showdown.js'
},
test: {
src: '<%= concat.dist.src %>',
dest: '.build/<%= pkg.name %>.js',
@ -42,14 +48,23 @@ module.exports = function (grunt) {
clean: ['.build/'],
uglify: {
options: {
sourceMap: true,
banner: '/*! <%= pkg.name %> v <%= pkg.version %> - <%= grunt.template.today("dd-mm-yyyy") %> */'
},
dist: {
options: {
sourceMap: true,
banner: '/*! <%= pkg.name %> v <%= pkg.version %> - <%= grunt.template.today("dd-mm-yyyy") %> */'
},
files: {
'dist/<%= pkg.name %>.min.js': ['<%= concat.dist.dest %>']
}
},
cli: {
options: {
sourceMap: false,
banner: '#!/usr/bin/env node'
},
files: {
'bin/showdown.js': ['<%= concat.cli.dest %>']
}
}
},
@ -136,6 +151,15 @@ module.exports = function (grunt) {
ignoreLeaks: false,
reporter: 'spec'
}
},
cli: {
src: 'test/node/testsuite.cli.js',
options: {
globals: ['should'],
timeout: 3000,
ignoreLeaks: false,
reporter: 'spec'
}
}
}
};
@ -202,14 +226,14 @@ module.exports = function (grunt) {
/**
* Tasks
*/
grunt.registerTask('test', ['clean', 'lint', 'concat:test', 'simplemocha:unit', 'simplemocha:functional', 'clean']);
grunt.registerTask('test-functional', ['concat:test', 'simplemocha:functional', 'clean']);
grunt.registerTask('test-unit', ['concat:test', 'simplemocha:unit', 'clean']);
grunt.registerTask('test-cli', ['clean', 'lint', 'concat:test', 'simplemocha:cli', 'clean']);
grunt.registerTask('performance', ['concat:test', 'performancejs', 'clean']);
grunt.registerTask('build', ['test', 'concat:dist', 'uglify', '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('prep-release', ['build', 'generate-changelog']);
grunt.registerTask('prep-release', ['build', 'performance', 'generate-changelog']);
// Default task(s).
grunt.registerTask('default', ['test']);

File diff suppressed because one or more lines are too long

34
dist/showdown.js vendored
View File

@ -1,4 +1,4 @@
;/*! showdown v 2.0.0-alpha1 - 01-03-2022 */
;/*! showdown v 2.0.0 - 03-03-2022 */
(function(){
/**
* Created by Tivie on 13-07-2015.
@ -95,77 +95,77 @@ function getDefaultOpts (simple) {
},
smartIndentationFix: {
defaultValue: false,
description: 'Tries to smartly fix indentation in es6 strings',
describe: 'Tries to smartly fix indentation in es6 strings',
type: 'boolean'
},
disableForced4SpacesIndentedSublists: {
defaultValue: false,
description: 'Disables the requirement of indenting nested sublists by 4 spaces',
describe: 'Disables the requirement of indenting nested sublists by 4 spaces',
type: 'boolean'
},
simpleLineBreaks: {
defaultValue: false,
description: 'Parses simple line breaks as <br> (GFM Style)',
describe: 'Parses simple line breaks as <br> (GFM Style)',
type: 'boolean'
},
requireSpaceBeforeHeadingText: {
defaultValue: false,
description: 'Makes adding a space between `#` and the header text mandatory (GFM Style)',
describe: 'Makes adding a space between `#` and the header text mandatory (GFM Style)',
type: 'boolean'
},
ghMentions: {
defaultValue: false,
description: 'Enables github @mentions',
describe: 'Enables github @mentions',
type: 'boolean'
},
ghMentionsLink: {
defaultValue: 'https://github.com/{u}',
description: 'Changes the link generated by @mentions. Only applies if ghMentions option is enabled.',
describe: 'Changes the link generated by @mentions. Only applies if ghMentions option is enabled.',
type: 'string'
},
encodeEmails: {
defaultValue: true,
description: 'Encode e-mail addresses through the use of Character Entities, transforming ASCII e-mail addresses into its equivalent decimal entities',
describe: 'Encode e-mail addresses through the use of Character Entities, transforming ASCII e-mail addresses into its equivalent decimal entities',
type: 'boolean'
},
openLinksInNewWindow: {
defaultValue: false,
description: 'Open all links in new windows',
describe: 'Open all links in new windows',
type: 'boolean'
},
backslashEscapesHTMLTags: {
defaultValue: false,
description: 'Support for HTML Tag escaping. ex: \<div>foo\</div>',
describe: 'Support for HTML Tag escaping. ex: \<div>foo\</div>',
type: 'boolean'
},
emoji: {
defaultValue: false,
description: 'Enable emoji support. Ex: `this is a :smile: emoji`',
describe: 'Enable emoji support. Ex: `this is a :smile: emoji`',
type: 'boolean'
},
underline: {
defaultValue: false,
description: 'Enable support for underline. Syntax is double or triple underscores: `__underline word__`. With this option enabled, underscores no longer parses into `<em>` and `<strong>`',
describe: 'Enable support for underline. Syntax is double or triple underscores: `__underline word__`. With this option enabled, underscores no longer parses into `<em>` and `<strong>`',
type: 'boolean'
},
ellipsis: {
defaultValue: true,
description: 'Replaces three dots with the ellipsis unicode character',
describe: 'Replaces three dots with the ellipsis unicode character',
type: 'boolean'
},
completeHTMLDocument: {
defaultValue: false,
description: 'Outputs a complete html document, including `<html>`, `<head>` and `<body>` tags',
describe: 'Outputs a complete html document, including `<html>`, `<head>` and `<body>` tags',
type: 'boolean'
},
metadata: {
defaultValue: false,
description: 'Enable support for document metadata (defined at the top of the document between `«««` and `»»»` or between `---` and `---`).',
describe: 'Enable support for document metadata (defined at the top of the document between `«««` and `»»»` or between `---` and `---`).',
type: 'boolean'
},
splitAdjacentBlockquotes: {
defaultValue: false,
description: 'Split adjacent blockquote blocks',
describe: 'Split adjacent blockquote blocks',
type: 'boolean'
},
moreStyling: {
@ -392,7 +392,7 @@ showdown.subParser = function (name, func) {
* Gets or registers an extension
* @static
* @param {string} name
* @param {object|function=} ext
* @param {object|object[]|function=} ext
* @returns {*}
*/
showdown.extension = function (name, ext) {

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

251
package-lock.json generated
View File

@ -9,14 +9,15 @@
"version": "2.0.0-alpha1",
"license": "MIT",
"dependencies": {
"jsdom": "^19.0.0",
"yargs": "^17.2.1"
"commander": "^9.0.0",
"jsdom": "^19.0.0"
},
"bin": {
"showdown": "bin/showdown.js"
},
"devDependencies": {
"chai": "^4.3.4",
"chai": "*",
"chai-match": "*",
"grunt": "^1.4.1",
"grunt-contrib-clean": "^2.0.0",
"grunt-contrib-concat": "^2.0.0",
@ -32,14 +33,14 @@
"quiet-grunt": "^0.2.0",
"semver": "^7.3.0",
"semver-sort": "^1.0.0",
"sinon": "^12.0.1",
"sinon": "*",
"source-map-support": "^0.5.21"
}
},
"node_modules/@eslint/eslintrc": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.1.0.tgz",
"integrity": "sha512-C1DfL7XX4nPqGd6jcP01W9pVM1HYCuUkFk1432D7F0v3JSlUIeOYn9oCoi3eoLZ+iwBSb29BMFxxny0YrrEZqg==",
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.0.tgz",
"integrity": "sha512-igm9SjJHNEJRiUnecP/1R5T3wKLEJ7pL6e2P+GUSfCd0dGjPYYZve08uzw8L2J8foVHFz+NGu12JxRcU2gGo6w==",
"dev": true,
"dependencies": {
"ajv": "^6.12.4",
@ -113,9 +114,9 @@
}
},
"node_modules/@sinonjs/fake-timers": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz",
"integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==",
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.0.tgz",
"integrity": "sha512-M8vapsv9qQupMdzrVzkn5rb9jG7aUTEPAZdMtME2PuBaefksFZVE2C1g4LBRTkF/k3nRDNbDc5tp5NFC1PEYxA==",
"dev": true,
"dependencies": {
"@sinonjs/commons": "^1.7.0"
@ -257,6 +258,7 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"dev": true,
"engines": {
"node": ">=8"
}
@ -265,6 +267,7 @@
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"dependencies": {
"color-convert": "^2.0.1"
},
@ -484,6 +487,12 @@
"node": ">=4"
}
},
"node_modules/chai-match": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/chai-match/-/chai-match-1.1.1.tgz",
"integrity": "sha1-OfsKLmt8j2OG3P6tSNFIqRX6bEY=",
"dev": true
},
"node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
@ -565,6 +574,7 @@
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
"integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
"dev": true,
"dependencies": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.0",
@ -575,6 +585,7 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"dependencies": {
"color-name": "~1.1.4"
},
@ -585,7 +596,8 @@
"node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"node_modules/colors": {
"version": "1.1.2",
@ -607,6 +619,14 @@
"node": ">= 0.8"
}
},
"node_modules/commander": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-9.0.0.tgz",
"integrity": "sha512-JJfP2saEKbQqvW+FI93OYUB4ByV5cizMpFMiiJI8xDbBvQvSkIk0VvQdn1CZ8mqAO8Loq2h0gYTYtDFUZUeERw==",
"engines": {
"node": "^12.20.0 || >=14"
}
},
"node_modules/compare-func": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/compare-func/-/compare-func-1.3.4.tgz",
@ -1274,7 +1294,8 @@
"node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true
},
"node_modules/entities": {
"version": "1.0.0",
@ -1295,6 +1316,7 @@
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
"integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
"dev": true,
"engines": {
"node": ">=6"
}
@ -1389,12 +1411,12 @@
}
},
"node_modules/eslint": {
"version": "8.9.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.9.0.tgz",
"integrity": "sha512-PB09IGwv4F4b0/atrbcMFboF/giawbBLVC7fyDamk5Wtey4Jh2K+rYaBhCAbUyEI4QzB1ly09Uglc9iCtFaG2Q==",
"version": "8.10.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.10.0.tgz",
"integrity": "sha512-tcI1D9lfVec+R4LE1mNDnzoJ/f71Kl/9Cv4nG47jOueCMBrCCKYXr4AUVS7go6mWYGFD4+EoN6+eXSrEbRzXVw==",
"dev": true,
"dependencies": {
"@eslint/eslintrc": "^1.1.0",
"@eslint/eslintrc": "^1.2.0",
"@humanwhocodes/config-array": "^0.9.2",
"ajv": "^6.10.0",
"chalk": "^4.0.0",
@ -1806,20 +1828,6 @@
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
},
"node_modules/fsevents": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
"dev": true,
"hasInstallScript": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
@ -1836,6 +1844,7 @@
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"dev": true,
"engines": {
"node": "6.* || 8.* || >= 10.*"
}
@ -2978,6 +2987,7 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true,
"engines": {
"node": ">=8"
}
@ -3951,24 +3961,6 @@
"url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
"node_modules/mocha/node_modules/yargs": {
"version": "16.2.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
"dev": true,
"dependencies": {
"cliui": "^7.0.2",
"escalade": "^3.1.1",
"get-caller-file": "^2.0.5",
"require-directory": "^2.1.1",
"string-width": "^4.2.0",
"y18n": "^5.0.5",
"yargs-parser": "^20.2.2"
},
"engines": {
"node": ">=10"
}
},
"node_modules/modify-values": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz",
@ -4732,6 +4724,7 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
"integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
@ -4928,16 +4921,16 @@
"dev": true
},
"node_modules/sinon": {
"version": "12.0.1",
"resolved": "https://registry.npmjs.org/sinon/-/sinon-12.0.1.tgz",
"integrity": "sha512-iGu29Xhym33ydkAT+aNQFBINakjq69kKO6ByPvTsm3yyIACfyQttRTP03aBP/I8GfhFmLzrnKwNNkr0ORb1udg==",
"version": "13.0.1",
"resolved": "https://registry.npmjs.org/sinon/-/sinon-13.0.1.tgz",
"integrity": "sha512-8yx2wIvkBjIq/MGY1D9h1LMraYW+z1X0mb648KZnKSdvLasvDu7maa0dFaNYdTDczFgbjNw2tOmWdTk9saVfwQ==",
"dev": true,
"dependencies": {
"@sinonjs/commons": "^1.8.3",
"@sinonjs/fake-timers": "^8.1.0",
"@sinonjs/samsam": "^6.0.2",
"@sinonjs/fake-timers": "^9.0.0",
"@sinonjs/samsam": "^6.1.1",
"diff": "^5.0.0",
"nise": "^5.1.0",
"nise": "^5.1.1",
"supports-color": "^7.2.0"
},
"funding": {
@ -5045,6 +5038,7 @@
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dev": true,
"dependencies": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
@ -5058,6 +5052,7 @@
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dev": true,
"dependencies": {
"ansi-regex": "^5.0.1"
},
@ -5252,9 +5247,9 @@
"dev": true
},
"node_modules/uglify-js": {
"version": "3.15.1",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.1.tgz",
"integrity": "sha512-FAGKF12fWdkpvNJZENacOH0e/83eG6JyVQyanIJaBXCN1J11TUQv1T1/z8S+Z0CG0ZPk1nPcreF/c7lrTd0TEQ==",
"version": "3.15.2",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.2.tgz",
"integrity": "sha512-peeoTk3hSwYdoc9nrdiEJk+gx1ALCtTjdYuKSXMTDqq7n1W7dHPqWDdSi+BPL0ni2YMeHD7hKUSdbj3TZauY2A==",
"dev": true,
"bin": {
"uglifyjs": "bin/uglifyjs"
@ -5459,6 +5454,7 @@
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"dev": true,
"dependencies": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
@ -5523,6 +5519,7 @@
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
"dev": true,
"engines": {
"node": ">=10"
}
@ -5534,20 +5531,21 @@
"dev": true
},
"node_modules/yargs": {
"version": "17.3.1",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.3.1.tgz",
"integrity": "sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA==",
"version": "16.2.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
"dev": true,
"dependencies": {
"cliui": "^7.0.2",
"escalade": "^3.1.1",
"get-caller-file": "^2.0.5",
"require-directory": "^2.1.1",
"string-width": "^4.2.3",
"string-width": "^4.2.0",
"y18n": "^5.0.5",
"yargs-parser": "^21.0.0"
"yargs-parser": "^20.2.2"
},
"engines": {
"node": ">=12"
"node": ">=10"
}
},
"node_modules/yargs-parser": {
@ -5607,14 +5605,6 @@
"node": ">=8"
}
},
"node_modules/yargs/node_modules/yargs-parser": {
"version": "21.0.0",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.0.tgz",
"integrity": "sha512-z9kApYUOCwoeZ78rfRYYWdiU/iNL6mwwYlkkZfJoyMR1xps+NEBX5X7XmRpxkZHhXJ6+Ey00IwKxBBSW9FIjyA==",
"engines": {
"node": ">=12"
}
},
"node_modules/yocto-queue": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
@ -5630,9 +5620,9 @@
},
"dependencies": {
"@eslint/eslintrc": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.1.0.tgz",
"integrity": "sha512-C1DfL7XX4nPqGd6jcP01W9pVM1HYCuUkFk1432D7F0v3JSlUIeOYn9oCoi3eoLZ+iwBSb29BMFxxny0YrrEZqg==",
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.0.tgz",
"integrity": "sha512-igm9SjJHNEJRiUnecP/1R5T3wKLEJ7pL6e2P+GUSfCd0dGjPYYZve08uzw8L2J8foVHFz+NGu12JxRcU2gGo6w==",
"dev": true,
"requires": {
"ajv": "^6.12.4",
@ -5696,9 +5686,9 @@
}
},
"@sinonjs/fake-timers": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz",
"integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==",
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.0.tgz",
"integrity": "sha512-M8vapsv9qQupMdzrVzkn5rb9jG7aUTEPAZdMtME2PuBaefksFZVE2C1g4LBRTkF/k3nRDNbDc5tp5NFC1PEYxA==",
"dev": true,
"requires": {
"@sinonjs/commons": "^1.7.0"
@ -5811,12 +5801,14 @@
"ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
"dev": true
},
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": {
"color-convert": "^2.0.1"
}
@ -5988,6 +5980,12 @@
"type-detect": "^4.0.5"
}
},
"chai-match": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/chai-match/-/chai-match-1.1.1.tgz",
"integrity": "sha1-OfsKLmt8j2OG3P6tSNFIqRX6bEY=",
"dev": true
},
"chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
@ -6045,6 +6043,7 @@
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
"integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
"dev": true,
"requires": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.0",
@ -6055,6 +6054,7 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"requires": {
"color-name": "~1.1.4"
}
@ -6062,7 +6062,8 @@
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"colors": {
"version": "1.1.2",
@ -6078,6 +6079,11 @@
"delayed-stream": "~1.0.0"
}
},
"commander": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-9.0.0.tgz",
"integrity": "sha512-JJfP2saEKbQqvW+FI93OYUB4ByV5cizMpFMiiJI8xDbBvQvSkIk0VvQdn1CZ8mqAO8Loq2h0gYTYtDFUZUeERw=="
},
"compare-func": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/compare-func/-/compare-func-1.3.4.tgz",
@ -6635,7 +6641,8 @@
"emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true
},
"entities": {
"version": "1.0.0",
@ -6655,7 +6662,8 @@
"escalade": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
"integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw=="
"integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
"dev": true
},
"escape-string-regexp": {
"version": "4.0.0",
@ -6719,12 +6727,12 @@
}
},
"eslint": {
"version": "8.9.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.9.0.tgz",
"integrity": "sha512-PB09IGwv4F4b0/atrbcMFboF/giawbBLVC7fyDamk5Wtey4Jh2K+rYaBhCAbUyEI4QzB1ly09Uglc9iCtFaG2Q==",
"version": "8.10.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.10.0.tgz",
"integrity": "sha512-tcI1D9lfVec+R4LE1mNDnzoJ/f71Kl/9Cv4nG47jOueCMBrCCKYXr4AUVS7go6mWYGFD4+EoN6+eXSrEbRzXVw==",
"dev": true,
"requires": {
"@eslint/eslintrc": "^1.1.0",
"@eslint/eslintrc": "^1.2.0",
"@humanwhocodes/config-array": "^0.9.2",
"ajv": "^6.10.0",
"chalk": "^4.0.0",
@ -7041,13 +7049,6 @@
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
},
"fsevents": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
"dev": true,
"optional": true
},
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
@ -7063,7 +7064,8 @@
"get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"dev": true
},
"get-func-name": {
"version": "2.0.0",
@ -7941,7 +7943,8 @@
"is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true
},
"is-glob": {
"version": "4.0.3",
@ -8686,21 +8689,6 @@
"requires": {
"has-flag": "^4.0.0"
}
},
"yargs": {
"version": "16.2.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
"dev": true,
"requires": {
"cliui": "^7.0.2",
"escalade": "^3.1.1",
"get-caller-file": "^2.0.5",
"require-directory": "^2.1.1",
"string-width": "^4.2.0",
"y18n": "^5.0.5",
"yargs-parser": "^20.2.2"
}
}
}
},
@ -9293,7 +9281,8 @@
"require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
"integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
"integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
"dev": true
},
"resolve": {
"version": "1.22.0",
@ -9437,16 +9426,16 @@
"dev": true
},
"sinon": {
"version": "12.0.1",
"resolved": "https://registry.npmjs.org/sinon/-/sinon-12.0.1.tgz",
"integrity": "sha512-iGu29Xhym33ydkAT+aNQFBINakjq69kKO6ByPvTsm3yyIACfyQttRTP03aBP/I8GfhFmLzrnKwNNkr0ORb1udg==",
"version": "13.0.1",
"resolved": "https://registry.npmjs.org/sinon/-/sinon-13.0.1.tgz",
"integrity": "sha512-8yx2wIvkBjIq/MGY1D9h1LMraYW+z1X0mb648KZnKSdvLasvDu7maa0dFaNYdTDczFgbjNw2tOmWdTk9saVfwQ==",
"dev": true,
"requires": {
"@sinonjs/commons": "^1.8.3",
"@sinonjs/fake-timers": "^8.1.0",
"@sinonjs/samsam": "^6.0.2",
"@sinonjs/fake-timers": "^9.0.0",
"@sinonjs/samsam": "^6.1.1",
"diff": "^5.0.0",
"nise": "^5.1.0",
"nise": "^5.1.1",
"supports-color": "^7.2.0"
}
},
@ -9543,6 +9532,7 @@
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dev": true,
"requires": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
@ -9553,6 +9543,7 @@
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dev": true,
"requires": {
"ansi-regex": "^5.0.1"
}
@ -9693,9 +9684,9 @@
"dev": true
},
"uglify-js": {
"version": "3.15.1",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.1.tgz",
"integrity": "sha512-FAGKF12fWdkpvNJZENacOH0e/83eG6JyVQyanIJaBXCN1J11TUQv1T1/z8S+Z0CG0ZPk1nPcreF/c7lrTd0TEQ==",
"version": "3.15.2",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.2.tgz",
"integrity": "sha512-peeoTk3hSwYdoc9nrdiEJk+gx1ALCtTjdYuKSXMTDqq7n1W7dHPqWDdSi+BPL0ni2YMeHD7hKUSdbj3TZauY2A==",
"dev": true
},
"unc-path-regex": {
@ -9856,6 +9847,7 @@
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"dev": true,
"requires": {
"ansi-styles": "^4.0.0",
"string-width": "^4.1.0",
@ -9893,7 +9885,8 @@
"y18n": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
"dev": true
},
"yallist": {
"version": "4.0.0",
@ -9902,24 +9895,18 @@
"dev": true
},
"yargs": {
"version": "17.3.1",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.3.1.tgz",
"integrity": "sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA==",
"version": "16.2.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
"dev": true,
"requires": {
"cliui": "^7.0.2",
"escalade": "^3.1.1",
"get-caller-file": "^2.0.5",
"require-directory": "^2.1.1",
"string-width": "^4.2.3",
"string-width": "^4.2.0",
"y18n": "^5.0.5",
"yargs-parser": "^21.0.0"
},
"dependencies": {
"yargs-parser": {
"version": "21.0.0",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.0.tgz",
"integrity": "sha512-z9kApYUOCwoeZ78rfRYYWdiU/iNL6mwwYlkkZfJoyMR1xps+NEBX5X7XmRpxkZHhXJ6+Ey00IwKxBBSW9FIjyA=="
}
"yargs-parser": "^20.2.2"
}
},
"yargs-parser": {

View File

@ -1,6 +1,6 @@
{
"name": "showdown",
"version": "2.0.0-alpha1",
"version": "2.0.0",
"description": "A Markdown to HTML converter written in Javascript",
"author": "Estevão Santos",
"homepage": "http://showdownjs.com/",
@ -38,8 +38,13 @@
"bin": {
"showdown": "bin/showdown.js"
},
"files": [
"bin",
"dist"
],
"devDependencies": {
"chai": "^4.3.4",
"chai": "*",
"chai-match": "*",
"grunt": "^1.4.1",
"grunt-contrib-clean": "^2.0.0",
"grunt-contrib-concat": "^2.0.0",
@ -55,11 +60,11 @@
"quiet-grunt": "^0.2.0",
"semver": "^7.3.0",
"semver-sort": "^1.0.0",
"sinon": "^12.0.1",
"sinon": "*",
"source-map-support": "^0.5.21"
},
"dependencies": {
"jsdom": "^19.0.0",
"yargs": "^17.2.1"
"commander": "^9.0.0"
}
}

File diff suppressed because one or more lines are too long

View File

@ -1,744 +1,43 @@
# Performance Tests for showdown
## [version 2.0.0-alpha1](https://github.com/showdownjs/showdown/tree/2.0.0-alpha1)
## [version 2.0.0](https://github.com/showdownjs/showdown/tree/2.0.0)
### Test Suite: Basic (50 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|Simple "Hello World"|0.330|9.462|0.086|
|performance.testfile.md|32.210|56.635|27.395|
|Simple "Hello World"|0.581|12.279|0.151|
|performance.testfile.md|35.491|79.405|29.046|
### Test Suite: subParsers (20 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|hashHTMLBlocks|4.055|7.506|2.413|
|anchors|0.342|0.600|0.286|
|autoLinks|0.091|0.193|0.070|
|blockQuotes|2.896|5.991|1.987|
|codeBlocks|0.303|1.578|0.190|
|codeSpans|0.285|0.533|0.237|
|detab|0.136|0.873|0.086|
|encodeAmpsAndAngles|0.104|0.166|0.097|
|encodeBackslashEscapes|0.081|0.141|0.068|
|encodeCode|0.942|1.342|0.850|
|escapeSpecialCharsWithinTagAttributes|0.212|0.436|0.159|
|githubCodeBlocks|0.176|0.305|0.143|
|hashBlock|0.047|0.094|0.036|
|hashElement|0.003|0.046|0.001|
|hashHTMLSpans|4.276|5.772|3.965|
|hashPreCodeTags|0.144|0.324|0.110|
|headers|1.418|4.438|1.062|
|horizontalRule|0.227|0.403|0.195|
|images|0.175|0.435|0.129|
|italicsAndBold|0.375|2.407|0.228|
|lists|2.918|3.716|2.526|
|outdent|0.164|0.270|0.138|
|paragraphs|6.444|8.106|5.759|
|spanGamut|4.294|6.106|3.842|
|strikethrough|0.005|0.090|0.000|
|stripLinkDefinitions|0.230|0.286|0.221|
|tables|0.002|0.034|0.001|
|unescapeSpecialChars|0.011|0.080|0.007|
## [version 1.9.0](https://github.com/showdownjs/showdown/tree/1.9.0)
### Test Suite: Basic (50 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|Simple "Hello World"|0.476|9.945|0.088|
|performance.testfile.md|32.208|61.885|28.234|
### Test Suite: subParsers (20 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|hashHTMLBlocks|5.827|23.030|2.429|
|anchors|0.363|0.636|0.294|
|autoLinks|0.120|0.319|0.071|
|blockQuotes|2.884|6.237|2.040|
|codeBlocks|0.290|1.131|0.189|
|codeSpans|0.314|0.875|0.234|
|detab|0.095|0.141|0.086|
|encodeAmpsAndAngles|0.155|1.186|0.095|
|encodeBackslashEscapes|0.087|0.144|0.069|
|encodeCode|0.918|1.279|0.865|
|escapeSpecialCharsWithinTagAttributes|0.245|0.711|0.156|
|githubCodeBlocks|0.160|0.291|0.142|
|hashBlock|0.043|0.067|0.038|
|hashElement|0.003|0.035|0.000|
|hashHTMLSpans|4.273|6.304|3.983|
|hashPreCodeTags|0.133|0.344|0.110|
|headers|1.454|3.874|1.098|
|horizontalRule|0.230|0.300|0.202|
|images|0.191|0.476|0.135|
|italicsAndBold|0.310|0.866|0.236|
|lists|3.135|4.249|2.662|
|outdent|0.167|0.262|0.140|
|paragraphs|6.383|7.885|5.680|
|spanGamut|4.106|5.310|3.698|
|strikethrough|0.005|0.087|0.000|
|stripLinkDefinitions|0.245|0.376|0.221|
|tables|0.003|0.049|0.001|
|unescapeSpecialChars|0.010|0.057|0.007|
## [version 1.8.4](https://github.com/showdownjs/showdown/tree/1.8.4)
### Test Suite: Basic (50 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|Simple "Hello World"|0.736|11.076|0.117|
|performance.testfile.md|32.918|62.427|27.941|
### Test Suite: subParsers (20 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|hashHTMLBlocks|5.260|17.333|2.340|
|anchors|0.522|2.898|0.307|
|autoLinks|0.124|0.300|0.071|
|blockQuotes|2.244|3.333|2.015|
|codeBlocks|0.244|0.817|0.190|
|codeSpans|0.354|1.201|0.243|
|detab|0.096|0.143|0.088|
|encodeAmpsAndAngles|0.138|0.198|0.096|
|encodeBackslashEscapes|0.093|0.184|0.071|
|encodeCode|0.961|1.611|0.858|
|escapeSpecialCharsWithinTagAttributes|0.252|0.520|0.158|
|githubCodeBlocks|0.262|0.390|0.161|
|hashBlock|0.052|0.129|0.037|
|hashElement|0.003|0.040|0.000|
|hashHTMLSpans|4.240|4.673|4.044|
|hashPreCodeTags|0.134|0.337|0.113|
|headers|1.412|4.475|1.077|
|horizontalRule|0.358|2.686|0.196|
|images|0.184|0.480|0.130|
|italicsAndBold|0.300|0.458|0.234|
|lists|3.074|4.651|2.626|
|outdent|0.204|0.931|0.137|
|paragraphs|6.406|8.020|5.821|
|spanGamut|4.136|6.038|3.840|
|strikethrough|0.007|0.132|0.000|
|stripLinkDefinitions|0.248|0.403|0.217|
|tables|0.003|0.040|0.001|
|unescapeSpecialChars|0.009|0.039|0.007|
## [version 1.8.3](https://github.com/showdownjs/showdown/tree/1.8.3)
### Test Suite: Basic (50 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|Simple "Hello World"|0.927|32.654|0.147|
|performance.testfile.md|32.485|62.282|28.403|
### Test Suite: subParsers (20 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|hashHTMLBlocks|5.454|18.356|2.385|
|anchors|0.504|3.110|0.290|
|autoLinks|0.114|0.284|0.069|
|blockQuotes|2.269|3.374|1.997|
|codeBlocks|0.250|0.840|0.192|
|codeSpans|0.352|1.231|0.249|
|detab|0.115|0.179|0.087|
|encodeAmpsAndAngles|0.105|0.162|0.095|
|encodeBackslashEscapes|0.108|0.235|0.075|
|encodeCode|0.994|1.915|0.847|
|escapeSpecialCharsWithinTagAttributes|0.237|0.475|0.160|
|githubCodeBlocks|0.202|0.771|0.151|
|hashBlock|0.071|0.493|0.039|
|hashElement|0.002|0.036|0.001|
|hashHTMLSpans|4.162|4.708|3.959|
|hashPreCodeTags|0.130|0.331|0.112|
|headers|1.409|4.622|1.044|
|horizontalRule|0.351|2.655|0.196|
|images|0.199|0.545|0.131|
|italicsAndBold|0.269|0.357|0.235|
|lists|3.057|4.403|2.686|
|outdent|0.153|0.307|0.136|
|paragraphs|6.455|7.901|5.708|
|spanGamut|4.256|5.542|3.930|
|strikethrough|0.005|0.089|0.000|
|stripLinkDefinitions|0.248|0.394|0.225|
|tables|0.002|0.028|0.001|
|unescapeSpecialChars|0.009|0.039|0.007|
## [version 1.8.2](https://github.com/showdownjs/showdown/tree/1.8.2)
### Test Suite: Basic (50 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|Simple "Hello World"|0.361|8.977|0.104|
|performance.testfile.md|33.109|56.478|29.179|
### Test Suite: subParsers (20 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|hashHTMLBlocks|5.488|20.714|2.321|
|anchors|0.506|3.158|0.292|
|autoLinks|0.141|0.365|0.072|
|blockQuotes|2.300|3.642|2.046|
|codeBlocks|0.243|0.877|0.189|
|codeSpans|0.268|1.176|0.159|
|detab|0.095|0.172|0.089|
|encodeAmpsAndAngles|0.108|0.230|0.097|
|encodeBackslashEscapes|0.078|0.119|0.074|
|encodeCode|1.002|1.544|0.851|
|escapeSpecialCharsWithinTagAttributes|0.256|0.566|0.164|
|githubCodeBlocks|0.253|0.999|0.152|
|hashBlock|0.042|0.080|0.037|
|hashElement|0.002|0.032|0.000|
|hashHTMLSpans|4.444|5.282|3.987|
|hashPreCodeTags|0.152|0.265|0.117|
|headers|1.465|4.970|1.059|
|horizontalRule|0.245|0.562|0.205|
|images|0.312|2.615|0.131|
|italicsAndBold|0.287|0.427|0.244|
|lists|3.261|4.098|2.792|
|outdent|0.179|0.377|0.141|
|paragraphs|6.661|9.047|5.884|
|spanGamut|4.561|6.173|4.009|
|strikethrough|0.005|0.097|0.000|
|stripLinkDefinitions|0.251|0.402|0.216|
|tables|0.006|0.086|0.001|
|unescapeSpecialChars|0.013|0.064|0.008|
## [version 1.8.0](https://github.com/showdownjs/showdown/tree/1.8.0)
### Test Suite: Basic (50 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|Simple "Hello World"|0.357|9.000|0.091|
|performance.testfile.md|31.434|57.439|26.735|
### Test Suite: subParsers (20 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|hashHTMLBlocks|4.177|7.661|2.346|
|anchors|0.542|3.749|0.300|
|autoLinks|0.087|0.183|0.069|
|blockQuotes|2.049|3.552|1.815|
|codeBlocks|0.264|1.163|0.185|
|codeSpans|0.271|0.790|0.163|
|detab|0.092|0.120|0.086|
|encodeAmpsAndAngles|0.106|0.146|0.097|
|encodeBackslashEscapes|0.091|0.152|0.077|
|encodeCode|0.962|1.552|0.862|
|escapeSpecialCharsWithinTagAttributes|0.239|0.487|0.173|
|githubCodeBlocks|0.222|0.914|0.140|
|hashBlock|0.063|0.402|0.035|
|hashElement|0.001|0.025|0.000|
|hashHTMLSpans|4.303|4.889|4.021|
|hashPreCodeTags|0.164|0.541|0.110|
|headers|1.159|3.779|0.968|
|horizontalRule|0.244|0.419|0.194|
|images|0.324|3.058|0.133|
|italicsAndBold|0.289|0.419|0.237|
|lists|2.671|3.139|2.494|
|outdent|0.159|0.253|0.139|
|paragraphs|5.594|6.833|5.159|
|spanGamut|5.069|9.600|4.128|
|strikethrough|0.003|0.062|0.000|
|stripLinkDefinitions|0.271|0.400|0.225|
|tables|0.002|0.031|0.000|
|unescapeSpecialChars|0.008|0.038|0.007|
## [version 1.7.6](https://github.com/showdownjs/showdown/tree/1.7.6)
### Test Suite: Basic (50 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|Simple "Hello World"|0.313|6.267|0.092|
|performance.testfile.md|30.962|54.583|26.381|
### Test Suite: subParsers (20 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|hashHTMLBlocks|4.099|7.072|2.360|
|anchors|0.574|4.502|0.294|
|autoLinks|0.087|0.210|0.066|
|blockQuotes|2.176|4.602|1.823|
|codeBlocks|0.282|0.885|0.193|
|codeSpans|0.265|0.764|0.166|
|detab|0.102|0.155|0.091|
|encodeAmpsAndAngles|0.107|0.175|0.098|
|encodeBackslashEscapes|0.120|0.872|0.073|
|encodeCode|0.983|1.842|0.873|
|escapeSpecialCharsWithinTagAttributes|0.301|0.389|0.277|
|githubCodeBlocks|0.204|0.889|0.146|
|hashBlock|0.063|0.415|0.035|
|hashElement|0.002|0.032|0.000|
|hashHTMLSpans|4.131|4.411|3.988|
|hashPreCodeTags|0.262|2.429|0.108|
|headers|1.264|4.308|0.953|
|horizontalRule|0.230|0.331|0.194|
|images|0.184|0.564|0.134|
|italicsAndBold|0.312|0.828|0.251|
|lists|2.642|3.274|2.451|
|outdent|0.159|0.240|0.144|
|paragraphs|6.724|12.672|5.367|
|spanGamut|4.991|9.206|4.173|
|strikethrough|0.003|0.058|0.000|
|stripLinkDefinitions|0.246|0.390|0.219|
|tables|0.002|0.044|0.000|
|unescapeSpecialChars|0.010|0.051|0.007|
## [version 1.7.5](https://github.com/showdownjs/showdown/tree/1.7.5)
### Test Suite: Basic (50 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|Simple "Hello World"|0.562|14.434|0.118|
|performance.testfile.md|30.396|57.886|26.628|
### Test Suite: subParsers (20 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|hashHTMLBlocks|4.280|8.392|2.357|
|anchors|0.602|5.341|0.285|
|autoLinks|0.092|0.193|0.065|
|blockQuotes|2.068|4.430|1.736|
|codeBlocks|0.279|0.937|0.181|
|codeSpans|0.222|0.592|0.158|
|detab|0.120|0.145|0.091|
|encodeAmpsAndAngles|0.116|0.222|0.096|
|encodeBackslashEscapes|0.140|0.914|0.071|
|encodeCode|1.195|2.009|0.861|
|escapeSpecialCharsWithinTagAttributes|0.307|0.468|0.269|
|githubCodeBlocks|0.197|0.837|0.144|
|hashBlock|0.060|0.442|0.036|
|hashElement|0.002|0.041|0.000|
|hashHTMLSpans|4.289|4.712|4.002|
|hashPreCodeTags|0.281|2.439|0.108|
|headers|1.221|4.603|0.908|
|horizontalRule|0.208|0.352|0.193|
|images|0.182|0.634|0.128|
|italicsAndBold|0.335|1.276|0.239|
|lists|3.143|6.411|2.393|
|outdent|0.398|0.585|0.159|
|paragraphs|5.926|11.596|4.961|
|spanGamut|4.443|6.012|4.024|
|strikethrough|0.003|0.055|0.000|
|stripLinkDefinitions|0.243|0.424|0.215|
|tables|0.003|0.049|0.000|
|unescapeSpecialChars|0.008|0.041|0.006|
## [version 1.7.4](https://github.com/showdownjs/showdown/tree/1.7.4)
### Test Suite: Basic (50 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|Simple "Hello World"|0.972|25.186|0.160|
|performance.testfile.md|30.397|61.913|26.550|
### Test Suite: subParsers (20 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|hashHTMLBlocks|3.999|6.603|2.314|
|anchors|0.527|3.823|0.285|
|autoLinks|0.090|0.188|0.063|
|blockQuotes|2.057|4.122|1.780|
|codeBlocks|0.247|1.085|0.186|
|codeSpans|0.263|1.017|0.162|
|detab|0.123|0.158|0.097|
|encodeAmpsAndAngles|0.118|0.171|0.096|
|encodeBackslashEscapes|0.079|0.146|0.071|
|encodeCode|0.945|1.453|0.866|
|escapeSpecialCharsWithinTagAttributes|0.285|0.438|0.246|
|githubCodeBlocks|0.225|0.969|0.142|
|hashBlock|0.068|0.577|0.036|
|hashElement|0.002|0.041|0.000|
|hashHTMLSpans|4.126|4.528|3.950|
|hashPreCodeTags|0.149|0.537|0.110|
|headers|1.171|3.877|0.884|
|horizontalRule|0.381|3.457|0.197|
|images|0.195|0.618|0.133|
|italicsAndBold|0.298|0.562|0.245|
|lists|3.790|6.139|2.612|
|outdent|0.167|0.276|0.139|
|paragraphs|5.349|6.076|4.897|
|spanGamut|4.370|6.111|3.946|
|strikethrough|0.003|0.048|0.000|
|stripLinkDefinitions|0.255|0.401|0.218|
|tables|0.002|0.033|0.000|
|unescapeSpecialChars|0.009|0.040|0.007|
## [version 1.7.3](https://github.com/showdownjs/showdown/tree/1.7.3)
### Test Suite: Basic (50 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|Simple "Hello World"|0.277|5.743|0.088|
|performance.testfile.md|30.733|54.768|26.972|
### Test Suite: subParsers (20 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|hashHTMLBlocks|4.316|8.271|2.339|
|anchors|0.525|3.812|0.288|
|autoLinks|0.085|0.220|0.063|
|blockQuotes|2.033|3.622|1.745|
|codeBlocks|0.251|1.060|0.178|
|codeSpans|0.246|0.749|0.157|
|detab|0.142|0.752|0.087|
|encodeAmpsAndAngles|0.100|0.129|0.095|
|encodeBackslashEscapes|0.079|0.125|0.070|
|encodeCode|0.977|1.774|0.852|
|escapeSpecialCharsWithinTagAttributes|0.271|0.441|0.244|
|githubCodeBlocks|0.235|0.985|0.139|
|hashBlock|0.068|0.550|0.036|
|hashElement|0.002|0.030|0.000|
|hashHTMLSpans|4.197|4.564|4.006|
|hashPreCodeTags|0.139|0.543|0.106|
|headers|1.148|4.214|0.880|
|horizontalRule|0.214|0.273|0.199|
|images|0.310|3.095|0.120|
|italicsAndBold|0.279|0.378|0.235|
|lists|3.843|8.278|2.630|
|outdent|0.193|0.386|0.144|
|paragraphs|5.541|8.153|4.836|
|spanGamut|4.638|5.775|4.142|
|strikethrough|0.003|0.052|0.000|
|stripLinkDefinitions|0.167|0.275|0.142|
|tables|0.002|0.036|0.000|
|unescapeSpecialChars|0.009|0.032|0.008|
## [version 1.7.2](https://github.com/showdownjs/showdown/tree/1.7.2)
### Test Suite: Basic (50 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|Simple "Hello World"|0.292|5.780|0.087|
|performance.testfile.md|30.396|53.860|26.054|
### Test Suite: subParsers (20 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|hashHTMLBlocks|4.303|7.798|2.377|
|anchors|0.347|0.647|0.287|
|autoLinks|0.088|0.165|0.063|
|blockQuotes|2.101|5.121|1.738|
|codeBlocks|0.239|0.878|0.184|
|codeSpans|0.252|0.628|0.160|
|detab|0.094|0.129|0.088|
|encodeAmpsAndAngles|0.131|0.733|0.093|
|encodeBackslashEscapes|0.080|0.116|0.070|
|encodeCode|0.939|1.480|0.857|
|escapeSpecialCharsWithinTagAttributes|0.285|0.473|0.243|
|githubCodeBlocks|0.214|1.047|0.140|
|hashBlock|0.068|0.553|0.036|
|hashElement|0.002|0.030|0.000|
|hashHTMLSpans|4.323|6.162|4.004|
|hashPreCodeTags|0.147|0.558|0.109|
|headers|1.176|4.491|0.884|
|horizontalRule|0.216|0.264|0.193|
|images|0.156|0.559|0.118|
|italicsAndBold|0.322|1.013|0.237|
|lists|2.753|5.613|2.328|
|outdent|0.163|0.232|0.140|
|paragraphs|5.109|6.168|4.741|
|spanGamut|4.423|6.149|4.001|
|strikethrough|0.003|0.051|0.000|
|stripLinkDefinitions|0.160|0.226|0.142|
|tables|0.002|0.043|0.000|
|unescapeSpecialChars|0.011|0.046|0.007|
## [version 1.7.1](https://github.com/showdownjs/showdown/tree/1.7.1)
### Test Suite: Basic (50 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|Simple "Hello World"|1.074|20.566|0.324|
|performance.testfile.md|30.463|82.116|26.022|
### Test Suite: subParsers (20 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|hashHTMLBlocks|4.233|9.062|2.359|
|anchors|0.351|0.763|0.286|
|autoLinks|0.089|0.190|0.065|
|blockQuotes|2.074|4.989|1.729|
|codeBlocks|0.256|0.937|0.179|
|codeSpans|0.242|0.839|0.158|
|detab|0.099|0.168|0.086|
|encodeAmpsAndAngles|0.131|0.646|0.093|
|encodeBackslashEscapes|0.076|0.140|0.070|
|encodeCode|0.994|1.706|0.865|
|escapeSpecialCharsWithinTagAttributes|0.267|0.375|0.250|
|githubCodeBlocks|0.192|0.966|0.140|
|hashBlock|0.059|0.397|0.036|
|hashElement|0.002|0.031|0.000|
|hashHTMLSpans|4.117|5.585|3.890|
|hashPreCodeTags|0.142|0.529|0.108|
|headers|1.145|4.103|0.864|
|horizontalRule|0.217|0.366|0.194|
|images|0.151|0.553|0.117|
|italicsAndBold|0.312|1.241|0.236|
|lists|4.023|7.077|2.498|
|outdent|0.175|0.261|0.148|
|paragraphs|6.557|8.645|4.997|
|spanGamut|5.073|6.347|4.137|
|strikethrough|0.006|0.110|0.000|
|stripLinkDefinitions|0.164|0.277|0.142|
|tables|0.004|0.080|0.000|
|unescapeSpecialChars|0.009|0.046|0.007|
## [version 1.7.0](https://github.com/showdownjs/showdown/tree/1.7.0)
### Test Suite: Basic (50 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|Simple "Hello World"|0.393|9.953|0.097|
|performance.testfile.md|29.416|54.253|25.949|
### Test Suite: subParsers (20 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|hashHTMLBlocks|4.062|7.185|2.326|
|anchors|0.488|4.086|0.281|
|autoLinks|0.086|0.200|0.063|
|blockQuotes|2.071|4.554|1.733|
|codeBlocks|0.253|0.864|0.178|
|codeSpans|0.261|0.592|0.160|
|detab|0.095|0.130|0.089|
|encodeAmpsAndAngles|0.103|0.192|0.095|
|encodeBackslashEscapes|0.106|0.589|0.071|
|encodeCode|0.927|1.182|0.835|
|escapeSpecialCharsWithinTagAttributes|0.276|0.617|0.245|
|githubCodeBlocks|0.195|0.980|0.139|
|hashBlock|0.062|0.483|0.035|
|hashElement|0.001|0.025|0.000|
|hashHTMLSpans|4.120|4.610|3.859|
|hashPreCodeTags|0.147|0.535|0.105|
|headers|1.308|4.253|0.856|
|horizontalRule|0.220|0.374|0.194|
|images|0.150|0.507|0.116|
|italicsAndBold|0.306|0.872|0.241|
|lists|3.447|4.893|2.407|
|outdent|0.267|0.868|0.181|
|paragraphs|5.867|8.331|4.970|
|spanGamut|5.039|7.124|4.116|
|strikethrough|0.004|0.073|0.000|
|stripLinkDefinitions|0.153|0.243|0.140|
|tables|0.002|0.044|0.000|
|unescapeSpecialChars|0.009|0.041|0.007|
## [version 1.6.4](https://github.com/showdownjs/showdown/tree/1.6.4)
### Test Suite: Basic (50 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|Simple "Hello World"|0.376|6.381|0.183|
|performance.testfile.md|33.835|61.049|30.186|
### Test Suite: subParsers (20 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|hashHTMLBlocks|2.564|8.347|1.871|
|anchors|0.499|4.222|0.270|
|autoLinks|0.080|0.174|0.061|
|blockQuotes|3.343|7.306|2.850|
|codeBlocks|0.221|0.822|0.172|
|codeSpans|0.229|0.744|0.156|
|detab|0.097|0.154|0.086|
|encodeAmpsAndAngles|0.117|0.200|0.094|
|encodeBackslashEscapes|0.086|0.230|0.068|
|encodeCode|0.885|1.165|0.816|
|escapeSpecialCharsWithinTagAttributes|0.298|0.495|0.240|
|githubCodeBlocks|0.183|0.785|0.133|
|hashBlock|0.044|0.098|0.035|
|hashElement|0.002|0.033|0.000|
|hashHTMLSpans|4.200|4.552|3.987|
|hashPreCodeTags|0.130|0.313|0.106|
|headers|1.224|4.010|0.945|
|horizontalRule|0.412|4.175|0.196|
|images|0.088|0.203|0.073|
|italicsAndBold|0.276|0.414|0.233|
|lists|5.005|6.109|4.663|
|outdent|0.152|0.337|0.139|
|paragraphs|5.336|7.117|4.843|
|spanGamut|4.450|6.153|3.857|
|strikethrough|0.003|0.049|0.000|
|stripLinkDefinitions|0.180|0.316|0.147|
|tables|0.003|0.055|0.000|
|unescapeSpecialChars|0.009|0.047|0.007|
## [version 1.6.3](https://github.com/showdownjs/showdown/tree/1.6.3)
### Test Suite: Basic (50 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|Simple "Hello World"|0.388|6.064|0.174|
|performance.testfile.md|26.899|49.063|24.845|
### Test Suite: subParsers (20 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|hashHTMLBlocks|2.616|8.181|1.899|
|anchors|0.515|4.691|0.264|
|autoLinks|0.093|0.188|0.073|
|blockQuotes|4.518|8.953|3.036|
|codeBlocks|0.223|0.348|0.188|
|codeSpans|0.318|1.095|0.177|
|detab|0.092|0.137|0.087|
|encodeAmpsAndAngles|0.044|0.089|0.038|
|encodeBackslashEscapes|0.108|0.265|0.078|
|encodeCode|1.535|9.896|0.865|
|escapeSpecialCharsWithinTagAttributes|0.294|0.523|0.253|
|githubCodeBlocks|0.208|0.790|0.142|
|hashBlock|0.042|0.123|0.036|
|hashElement|0.002|0.029|0.000|
|hashHTMLSpans|0.410|1.598|0.240|
|hashPreCodeTags|0.132|0.395|0.110|
|headers|1.015|1.502|0.806|
|horizontalRule|0.220|0.357|0.195|
|images|0.158|0.978|0.077|
|italicsAndBold|0.288|0.639|0.241|
|lists|5.151|6.331|4.629|
|outdent|0.180|0.363|0.143|
|paragraphs|4.548|6.309|4.002|
|spanGamut|1.519|1.864|1.372|
|strikethrough|0.003|0.065|0.000|
|stripLinkDefinitions|0.179|0.313|0.144|
|tables|0.004|0.063|0.000|
|unescapeSpecialChars|0.011|0.049|0.007|
## [version 1.6.2](https://github.com/showdownjs/showdown/tree/1.6.2)
### Test Suite: Basic (50 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|Simple "Hello World"|0.613|5.894|0.169|
|performance.testfile.md|25.970|62.882|23.710|
### Test Suite: subParsers (20 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|hashHTMLBlocks|2.669|8.479|1.885|
|anchors|0.500|3.841|0.268|
|autoLinks|0.098|0.211|0.072|
|blockQuotes|3.222|5.826|2.791|
|codeBlocks|0.177|0.371|0.157|
|codeSpans|0.218|0.483|0.151|
|detab|0.135|0.655|0.085|
|encodeAmpsAndAngles|0.042|0.118|0.036|
|encodeBackslashEscapes|0.080|0.133|0.068|
|encodeCode|0.560|0.982|0.484|
|escapeSpecialCharsWithinTagAttributes|0.353|0.568|0.291|
|githubCodeBlocks|0.180|0.773|0.127|
|hashBlock|0.058|0.312|0.037|
|hashElement|0.003|0.046|0.000|
|hashHTMLSpans|0.475|2.325|0.234|
|hashPreCodeTags|0.122|0.307|0.107|
|headers|0.858|0.954|0.780|
|horizontalRule|0.227|0.418|0.197|
|images|0.171|1.453|0.077|
|italicsAndBold|0.101|0.202|0.088|
|lists|4.931|5.460|4.556|
|outdent|0.163|0.315|0.142|
|paragraphs|3.790|5.564|3.278|
|spanGamut|1.442|2.012|1.203|
|strikethrough|0.004|0.082|0.000|
|stripBlankLines|0.086|0.130|0.080|
|stripLinkDefinitions|0.160|0.217|0.145|
|tables|0.004|0.076|0.000|
|unescapeSpecialChars|0.010|0.058|0.007|
## [version 1.6.1](https://github.com/showdownjs/showdown/tree/1.6.1)
### Test Suite: Basic (50 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|Simple "Hello World"|0.317|5.498|0.161|
|readme.md|26.014|46.799|24.245|
### Test Suite: subParsers (20 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|hashHTMLBlocks|2.641|7.792|1.936|
|anchors|0.475|4.063|0.259|
|autoLinks|0.089|0.197|0.069|
|blockQuotes|3.213|6.054|2.880|
|codeBlocks|0.162|0.269|0.153|
|codeSpans|0.169|0.399|0.141|
|detab|0.125|0.665|0.086|
|encodeAmpsAndAngles|0.042|0.089|0.038|
|encodeBackslashEscapes|0.076|0.133|0.068|
|encodeCode|0.577|0.970|0.479|
|escapeSpecialCharsWithinTagAttributes|0.246|0.350|0.221|
|githubCodeBlocks|0.177|0.815|0.125|
|hashBlock|0.065|0.430|0.038|
|hashElement|0.002|0.034|0.000|
|hashHTMLSpans|0.424|2.321|0.241|
|hashPreCodeTags|0.122|0.238|0.104|
|headers|0.804|0.946|0.726|
|horizontalRule|0.219|0.274|0.194|
|images|0.124|0.902|0.071|
|italicsAndBold|0.101|0.150|0.090|
|lists|4.939|5.421|4.624|
|outdent|0.165|0.337|0.140|
|paragraphs|3.495|4.555|3.171|
|spanGamut|1.319|1.992|1.147|
|strikethrough|0.007|0.143|0.000|
|stripBlankLines|0.094|0.155|0.082|
|stripLinkDefinitions|0.176|0.311|0.146|
|tables|0.002|0.039|0.000|
|unescapeSpecialChars|0.008|0.034|0.007|
## [version 1.6.0](https://github.com/showdownjs/showdown/tree/1.6.0)
### Test Suite: Basic (50 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|Simple "Hello World"|0.308|5.369|0.157|
|readme.md|25.818|47.795|23.775|
### Test Suite: subParsers (20 cycles)
| test | avgTime | max | min |
|:-----|--------:|----:|----:|
|hashHTMLBlocks|2.653|8.558|1.880|
|anchors|0.517|4.142|0.271|
|autoLinks|0.089|0.194|0.071|
|blockGamut|17.372|22.941|14.082|
|blockQuotes|3.011|4.110|2.774|
|codeBlocks|0.243|0.834|0.193|
|codeSpans|0.227|0.458|0.191|
|detab|0.095|0.133|0.090|
|encodeAmpsAndAngles|0.040|0.073|0.038|
|encodeBackslashEscapes|0.100|0.510|0.068|
|encodeCode|0.532|0.706|0.479|
|escapeSpecialCharsWithinTagAttributes|0.386|0.702|0.327|
|githubCodeBlocks|0.214|0.778|0.156|
|hashBlock|0.057|0.280|0.035|
|hashElement|0.002|0.033|0.000|
|hashHTMLSpans|0.384|1.997|0.236|
|hashPreCodeTags|0.133|0.200|0.116|
|headers|0.944|2.468|0.782|
|images|0.120|0.486|0.086|
|italicsAndBold|0.111|0.445|0.088|
|lists|5.783|13.249|4.464|
|outdent|0.306|0.956|0.225|
|paragraphs|6.583|8.811|4.499|
|spanGamut|2.437|3.067|1.647|
|strikethrough|0.005|0.100|0.000|
|stripBlankLines|0.121|0.175|0.092|
|stripLinkDefinitions|0.247|0.573|0.171|
|tables|0.006|0.099|0.000|
|unescapeSpecialChars|0.017|0.066|0.011|
|hashHTMLBlocks|4.561|7.807|2.461|
|anchors|2.910|6.510|1.056|
|blockQuotes|4.142|19.023|2.541|
|codeBlocks|0.264|0.858|0.194|
|codeSpans|0.365|1.421|0.278|
|detab|0.055|0.116|0.047|
|encodeAmpsAndAngles|0.145|0.796|0.092|
|encodeBackslashEscapes|0.087|0.266|0.063|
|encodeCode|0.605|1.144|0.522|
|escapeSpecialCharsWithinTagAttributes|0.206|0.287|0.184|
|githubCodeBlocks|0.251|1.003|0.192|
|hashBlock|0.038|0.104|0.034|
|hashElement|0.005|0.053|0.001|
|hashHTMLSpans|5.229|9.835|4.240|
|hashPreCodeTags|0.155|0.705|0.117|
|headers|2.278|4.825|1.631|
|horizontalRule|0.159|0.276|0.148|
|images|0.159|0.390|0.124|
|italicsAndBold|0.280|0.773|0.211|
|lists|4.253|8.173|3.146|
|outdent|0.181|0.238|0.162|
|paragraphs|8.968|11.331|7.857|
|spanGamut|2.985|4.162|2.486|
|strikethrough|0.007|0.099|0.001|
|stripLinkDefinitions|1.911|2.855|1.447|
|tables|0.008|0.127|0.002|
|unescapeSpecialChars|0.013|0.073|0.010|

View File

@ -1,50 +1,324 @@
/**
* Created by tivie
*/
'use strict';
var fs = require('fs'),
json = JSON.parse(fs.readFileSync('package.json', 'utf8')),
version = json.version,
Command = require('commander').Command,
program = new Command(),
showdown;
var yargs = require('yargs');
yargs
.version()
.alias('v', 'version')
.option('h', {
alias: 'help',
description: 'Show help'
})
.option('q', {
alias: 'quiet',
description: 'Quiet mode. Only print errors',
type: 'boolean',
default: false
})
.option('m', {
alias: 'mute',
description: 'Mute mode. Does not print anything',
type: 'boolean',
default: false
})
.usage('Usage: showdown <command> [options]')
.demand(1, 'You must provide a valid command')
.command('makehtml', 'Converts markdown into html')
.example('showdown makehtml -i foo.md -o bar.html', 'Converts \'foo.md\' to \'bar.html\'')
.wrap(yargs.terminalWidth());
var argv = yargs.argv,
command = argv._[0];
if (command === 'makehtml') {
require('./makehtml.cmd.js').run(function (err) {
if (err) {
console.error(err);
}
});
// require shodown. We use conditional loading for each use case
if (fs.existsSync('../dist/showdown.js')) {
// production. File lives in bin directory
showdown = require('../dist/showdown');
} else if (fs.existsSync('../../.build/showdown.js')) {
// testing envo, uses the concatenated stuff for testing
showdown = require('../../.build/showdown.js');
} else {
yargs.showHelp();
process.exit(0);
// cold testing (manual) of cli.js in the src file. We load the dist file
showdown = require('../../dist/showdown');
}
if (argv.help) {
yargs.showHelp();
process.exit(0);
program
.name('showdown')
.description('CLI to Showdownjs markdown parser v' + version)
.version(version)
.usage('<command> [options]')
.option('-q, --quiet', 'Quiet mode. Only print errors')
.option('-m, --mute', 'Mute mode. Does not print anything');
program.command('makehtml')
.description('Converts markdown into html')
.addHelpText('after', '\n\nExamples:')
.addHelpText('after', ' showdown makehtml -i Reads from stdin and outputs to stdout')
.addHelpText('after', ' showdown makehtml -i foo.md -o bar.html Reads \'foo.md\' and writes to \'bar.html\'')
.addHelpText('after', ' showdown makehtml -i --flavor="github" Parses stdin using GFM style')
.addHelpText('after', '\nNote for windows users:')
.addHelpText('after', 'When reading from stdin, use option -u to set the proper encoding or run `chcp 65001` prior to calling showdown cli to set the command line to utf-8')
.option('-i, --input [file]', 'Input source. Usually a md file. If omitted or empty, reads from stdin. Windows users see note below.', true)
.option('-o, --output [file]', 'Output target. Usually a html file. If omitted or empty, writes to stdout', true)
.option('-u, --encoding <encoding>', 'Sets the input encoding', 'utf8')
.option('-y, --output-encoding <encoding>', 'Sets the output encoding', 'utf8')
.option('-a, --append', 'Append data to output instead of overwriting. Ignored if writing to stdout', false)
.option('-e, --extensions <extensions...>', 'Load the specified extensions. Should be valid paths to node compatible extensions')
.option('-p, --flavor <flavor>', 'Run with a predetermined flavor of options. Default is vanilla', 'vanilla')
.option('-c, --config <config...>', 'Enables showdown makehtml parser config options. Overrides flavor')
.option('--config-help', 'Shows configuration options for showdown parser')
.action(makehtmlCommand);
program.parse();
//
// HELPER FUCNTIONS
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Messenger helper object to the CLI
* @param {string} writeMode
* @param {boolean} supress
* @param {boolean} mute
* @constructor
*/
function Messenger (writeMode, supress, mute) {
'use strict';
writeMode = writeMode || 'stderr';
supress = (!!supress || !!mute);
mute = !!mute;
this._print = (writeMode === 'stdout') ? console.log : console.error;
this.errorExit = function (e) {
if (!mute) {
console.error('ERROR: ' + e.message);
console.error('Run \'showdown <command> -h\' for help');
}
process.exit(1);
};
this.okExit = function () {
if (!mute) {
this._print('\n');
this._print('DONE!');
}
process.exit(0);
};
this.printMsg = function (msg) {
if (supress || mute || !msg) {
return;
}
this._print(msg);
};
this.printError = function (msg) {
if (mute) {
return;
}
console.error(msg);
};
}
/**
* Helper function to show Showdown Options
*/
function showShowdownOptions () {
'use strict';
var showdownOptions = showdown.getDefaultOptions(false);
console.log('\nshowdown makehtml config options:');
// show showdown options
for (var sopt in showdownOptions) {
if (showdownOptions.hasOwnProperty(sopt)) {
console.log(' ' + sopt + ':', '[default=' + showdownOptions[sopt].defaultValue + ']',showdownOptions[sopt].describe);
}
}
console.log('\n\nExample: showdown makehtml -c openLinksInNewWindow ghMentions ghMentionsLink="https://google.com"');
}
/**
* Helper function to parse showdown options
* @param {{}} configOptions
* @param {{}} defaultOptions
* @returns {{}}
*/
function parseShowdownOptions (configOptions, defaultOptions) {
'use strict';
var shOpt = defaultOptions;
// first prepare passed options
if (configOptions) {
for (var i = 0; i < configOptions.length; ++i) {
var opt = configOptions[i],
key = configOptions[i],
val = true;
if (/=/.test(opt)) {
key = opt.split('=')[0];
val = opt.split('=')[1];
}
shOpt[key] = val;
}
}
return shOpt;
}
/**
* Reads stdin
* @returns {string}
*/
function readFromStdIn (encoding) {
'use strict';
var size = fs.fstatSync(process.stdin.fd).size;
if (size <= 0) {
throw new Error('Could not read from stdin, reason: stdin is empty');
}
encoding = encoding || 'utf8';
try {
return size > 0 ? fs.readFileSync(process.stdin.fd, encoding).toString() : '';
} catch (e) {
throw new Error('Could not read from stdin, reason: ' + e.message);
}
}
/**
* Reads from a file
* @param {string} file Filepath to dile
* @param {string} encoding Encoding of the file
* @returns {Buffer}
*/
function readFromFile (file, encoding) {
'use strict';
try {
return fs.readFileSync(file, encoding);
} catch (err) {
throw new Error('Could not read from file ' + file + ', reason: ' + err.message);
}
}
/**
* Writes to stdout
* @param {string} html
* @returns {boolean}
*/
function writeToStdOut (html) {
'use strict';
if (!process.stdout.write(html)) {
throw new Error('Could not write to StdOut');
}
}
/**
* Writes to file
* @param {string} html HTML to write
* @param {string} file Filepath
* @param {boolean} append If the result should be appended
*/
function writeToFile (html, file, append) {
'use strict';
// If a flag is passed, it means we should append instead of overwriting.
// Only works with files, obviously
var write = (append) ? fs.appendFileSync : fs.writeFileSync;
try {
write(file, html);
} catch (err) {
throw new Error('Could not write to file ' + file + ', readon: ' + err.message);
}
}
/**
* makehtml command
* @param {{}} options
* @param {Command} cmd
*/
function makehtmlCommand (options, cmd) {
'use strict';
// show configuration options for showdown helper if configHelp was passed
if (options.configHelp) {
showShowdownOptions();
return;
}
var quiet = !!(cmd.parent._optionValues.quiet),
mute = !!(cmd.parent._optionValues.mute),
readMode = (!options.input || options.input === '' || options.input === true) ? 'stdin' : 'file',
writeMode = (!options.output || options.output === '' || options.output === true) ? 'stdout' : 'file',
msgMode = (writeMode === 'file') ? 'stdout' : 'stderr',
// initiate Messenger helper, can maybe be replaced with commanderjs internal stuff
messenger = new Messenger(msgMode, quiet, mute),
defaultOptions = showdown.getDefaultOptions(true),
md, html;
// deal with flavor first since config flag overrides flavor individual options
if (options.flavor) {
messenger.printMsg('Enabling flavor ' + options.flavor + '...');
defaultOptions = showdown.getFlavorOptions(options.flavor);
if (!defaultOptions) {
messenger.errorExit(new Error('Flavor ' + options.flavor + ' is not recognised'));
return;
}
messenger.printMsg('OK!');
}
// store config options in the options.config as an object
options.config = parseShowdownOptions(options.config, defaultOptions);
// print enabled options
for (var o in options.config) {
if (options.config.hasOwnProperty(o) && options.config[o] === true) {
messenger.printMsg('Enabling option ' + o);
}
}
// initialize the converter
messenger.printMsg('\nInitializing converter...');
var converter;
try {
converter = new showdown.Converter(options.config);
} catch (e) {
messenger.errorExit(e);
return;
}
messenger.printMsg('OK!');
// load extensions
if (options.extensions) {
messenger.printMsg('\nLoading extensions...');
for (var i = 0; i < options.extensions.length; ++i) {
try {
messenger.printMsg(options.extensions[i]);
var ext = require(options.extensions[i]);
converter.addExtension(ext, options.extensions[i]);
messenger.printMsg(options.extensions[i] + ' loaded...');
} catch (e) {
messenger.printError('Could not load extension ' + options.extensions[i] + '. Reason:');
messenger.errorExit(e);
}
}
}
messenger.printMsg('...');
// read the input
messenger.printMsg('Reading data from ' + readMode + '...');
if (readMode === 'stdin') {
try {
md = readFromStdIn(options.encoding);
} catch (err) {
messenger.errorExit(err);
return;
}
} else {
try {
md = readFromFile(options.input, options.encoding);
} catch (err) {
messenger.errorExit(err);
return;
}
}
// process the input
messenger.printMsg('Parsing markdown...');
html = converter.makeHtml(md);
// write the output
messenger.printMsg('Writing data to ' + writeMode + '...');
if (writeMode === 'stdout') {
try {
writeToStdOut(html);
} catch (err) {
messenger.errorExit(err);
return;
}
} else {
try {
writeToFile(html, options.output, options.append);
} catch (err) {
messenger.errorExit(err);
return;
}
}
messenger.okExit();
}

View File

@ -1,200 +0,0 @@
var yargs = require('yargs'),
fs = require('fs'),
Messenger = require('./messenger.js'),
showdown = require('../../dist/showdown'),
showdownOptions = showdown.getDefaultOptions(false);
yargs.reset()
.usage('Usage: showdown makehtml [options]')
.example('showdown makehtml -i', 'Reads from stdin and outputs to stdout')
.example('showdown makehtml -i foo.md -o bar.html', 'Reads \'foo.md\' and writes to \'bar.html\'')
.example('showdown makehtml -i --flavor="github"', 'Parses stdin using GFM style')
.version()
.alias('v', 'version')
.config('c')
.alias('c', 'config')
.help('h')
.alias('h', 'help')
.option('i', {
alias : 'input',
describe: 'Input source. Usually a md file. If omitted or empty, reads from stdin',
type: 'string'
})
.option('o', {
alias : 'output',
describe: 'Output target. Usually a html file. If omitted or empty, writes to stdout',
type: 'string',
default: false
})
.option('u', {
alias : 'encoding',
describe: 'Input encoding',
type: 'string'
})
.option('a', {
alias : 'append',
describe: 'Append data to output instead of overwriting',
type: 'string',
default: false
})
.option('e', {
alias : 'extensions',
describe: 'Load the specified extensions. Should be valid paths to node compatible extensions',
type: 'array'
})
.option('p', {
alias : 'flavor',
describe: 'Run with a predetermined flavor of options. Default is vanilla',
type: 'string'
})
.option('q', {
alias: 'quiet',
description: 'Quiet mode. Only print errors',
type: 'boolean',
default: false
})
.option('m', {
alias: 'mute',
description: 'Mute mode. Does not print anything',
type: 'boolean',
default: false
});
// load showdown default options
for (var opt in showdownOptions) {
if (showdownOptions.hasOwnProperty(opt)) {
if (showdownOptions[opt].defaultValue === false) {
showdownOptions[opt].default = null;
} else {
showdownOptions[opt].default = showdownOptions[opt].defaultValue;
}
yargs.option(opt, showdownOptions[opt]);
}
}
function run (cb) {
'use strict';
var argv = yargs.argv,
readMode = (!argv.i || argv.i === '') ? 'stdin' : 'file',
writeMode = (!argv.o || argv.o === '') ? 'stdout' : 'file',
msgMode = (writeMode === 'file') ? 'stdout' : 'stderr',
/**
* MSG object
* @type {Messenger}
*/
messenger = new Messenger(msgMode, argv.q, argv.m),
write = (writeMode === 'stdout') ? writeToStdOut : writeToFile,
enc = argv.encoding || 'utf8',
flavor = argv.p,
append = argv.a || false,
options = parseOptions(flavor),
converter = new showdown.Converter(options),
html;
// Load extensions
if (argv.e) {
messenger.printMsg('Loading extensions');
for (var i = 0; i < argv.e.length; ++i) {
try {
var ext = require(argv.e[i]);
converter.addExtension(ext, argv.e[i]);
} catch (e) {
messenger.printError('Could not load extension ' + argv.e[i] + '. Reason:');
messenger.errorExit(e);
}
}
}
messenger.printMsg('...');
// read the input
messenger.printMsg('Reading data from ' + readMode + '...');
readFrom(argv.i, enc, function (err, md) {
if (err) {
return cb(err);
}
// process the input
messenger.printMsg('Parsing markdown...');
html = converter.makeHtml(md);
// write the output
messenger.printMsg('Writing data to ' + writeMode + '...');
write(html, append);
messenger.okExit();
cb();
});
function parseOptions (flavor) {
var options = {},
flavorOpts = showdown.getFlavorOptions(flavor) || {};
// if flavor is not undefined, let's tell the user we're loading that preset
if (flavor) {
messenger.printMsg('Loading ' + flavor + ' flavor.');
}
for (var opt in argv) {
if (argv.hasOwnProperty(opt)) {
// first we load the default options
if (showdownOptions.hasOwnProperty(opt) && showdownOptions[opt].default !== null) {
options[opt] = showdownOptions[opt].default;
}
// we now override defaults with flavor, if a flavor was indeed passed
if (flavorOpts.hasOwnProperty(opt)) {
options[opt] = flavorOpts[opt];
}
// lastly we override with explicit passed options
// being careful not to pass CLI specific options, such as -v, -h or --extensions
if (showdownOptions.hasOwnProperty(opt)) {
if (argv[opt] === true) {
messenger.printMsg('Enabling option ' + opt);
options[opt] = argv[opt];
} else if (argv[opt] === false) {
options[opt] = argv[opt];
}
}
}
}
return options;
}
function readFrom (src, enc, cb) {
var stream = process.stdin;
if (src && src.length) {
stream = fs.createReadStream(src, {encoding: enc});
} else {
process.stdin.setEncoding(enc);
process.stdin.resume();
}
var data = '';
stream.on('data', function (chunk) {
data += chunk.toString();
});
stream.on('end',function () {
cb(null, data);
});
stream.on('error', cb);
}
function writeToStdOut (html) {
return process.stdout.write(html);
}
function writeToFile (html, append) {
// If a flag is passed, it means we should append instead of overwriting.
// Only works with files, obviously
var write = (append) ? fs.appendFileSync : fs.writeFileSync;
try {
write(argv.o, html);
} catch (err) {
messenger.errorExit(err);
}
}
}
module.exports = exports = {
run: run
};

View File

@ -1,40 +0,0 @@
function Messenger (writeMode, supress, mute) {
'use strict';
writeMode = writeMode || 'stderr';
supress = (!!supress || !!mute);
mute = !!mute;
this._print = (writeMode === 'stdout') ? console.log : console.error;
this.errorExit = function (e) {
if (!mute) {
console.error('ERROR: ' + e.message);
console.error('Run \'showdown <command> -h\' for help');
}
process.exit(1);
};
this.okExit = function () {
if (!mute) {
this._print('\n');
this._print('DONE!');
}
process.exit(0);
};
this.printMsg = function (msg) {
if (supress || mute || !msg) {
return;
}
this._print(msg);
};
this.printError = function (msg) {
if (mute) {
return;
}
console.error(msg);
};
}
module.exports = Messenger;

View File

@ -93,77 +93,77 @@ function getDefaultOpts (simple) {
},
smartIndentationFix: {
defaultValue: false,
description: 'Tries to smartly fix indentation in es6 strings',
describe: 'Tries to smartly fix indentation in es6 strings',
type: 'boolean'
},
disableForced4SpacesIndentedSublists: {
defaultValue: false,
description: 'Disables the requirement of indenting nested sublists by 4 spaces',
describe: 'Disables the requirement of indenting nested sublists by 4 spaces',
type: 'boolean'
},
simpleLineBreaks: {
defaultValue: false,
description: 'Parses simple line breaks as <br> (GFM Style)',
describe: 'Parses simple line breaks as <br> (GFM Style)',
type: 'boolean'
},
requireSpaceBeforeHeadingText: {
defaultValue: false,
description: 'Makes adding a space between `#` and the header text mandatory (GFM Style)',
describe: 'Makes adding a space between `#` and the header text mandatory (GFM Style)',
type: 'boolean'
},
ghMentions: {
defaultValue: false,
description: 'Enables github @mentions',
describe: 'Enables github @mentions',
type: 'boolean'
},
ghMentionsLink: {
defaultValue: 'https://github.com/{u}',
description: 'Changes the link generated by @mentions. Only applies if ghMentions option is enabled.',
describe: 'Changes the link generated by @mentions. Only applies if ghMentions option is enabled.',
type: 'string'
},
encodeEmails: {
defaultValue: true,
description: 'Encode e-mail addresses through the use of Character Entities, transforming ASCII e-mail addresses into its equivalent decimal entities',
describe: 'Encode e-mail addresses through the use of Character Entities, transforming ASCII e-mail addresses into its equivalent decimal entities',
type: 'boolean'
},
openLinksInNewWindow: {
defaultValue: false,
description: 'Open all links in new windows',
describe: 'Open all links in new windows',
type: 'boolean'
},
backslashEscapesHTMLTags: {
defaultValue: false,
description: 'Support for HTML Tag escaping. ex: \<div>foo\</div>',
describe: 'Support for HTML Tag escaping. ex: \<div>foo\</div>',
type: 'boolean'
},
emoji: {
defaultValue: false,
description: 'Enable emoji support. Ex: `this is a :smile: emoji`',
describe: 'Enable emoji support. Ex: `this is a :smile: emoji`',
type: 'boolean'
},
underline: {
defaultValue: false,
description: 'Enable support for underline. Syntax is double or triple underscores: `__underline word__`. With this option enabled, underscores no longer parses into `<em>` and `<strong>`',
describe: 'Enable support for underline. Syntax is double or triple underscores: `__underline word__`. With this option enabled, underscores no longer parses into `<em>` and `<strong>`',
type: 'boolean'
},
ellipsis: {
defaultValue: true,
description: 'Replaces three dots with the ellipsis unicode character',
describe: 'Replaces three dots with the ellipsis unicode character',
type: 'boolean'
},
completeHTMLDocument: {
defaultValue: false,
description: 'Outputs a complete html document, including `<html>`, `<head>` and `<body>` tags',
describe: 'Outputs a complete html document, including `<html>`, `<head>` and `<body>` tags',
type: 'boolean'
},
metadata: {
defaultValue: false,
description: 'Enable support for document metadata (defined at the top of the document between `«««` and `»»»` or between `---` and `---`).',
describe: 'Enable support for document metadata (defined at the top of the document between `«««` and `»»»` or between `---` and `---`).',
type: 'boolean'
},
splitAdjacentBlockquotes: {
defaultValue: false,
description: 'Split adjacent blockquote blocks',
describe: 'Split adjacent blockquote blocks',
type: 'boolean'
},
moreStyling: {

View File

@ -187,7 +187,7 @@ showdown.subParser = function (name, func) {
* Gets or registers an extension
* @static
* @param {string} name
* @param {object|function=} ext
* @param {object|object[]|function=} ext
* @returns {*}
*/
showdown.extension = function (name, ext) {

View File

@ -1,3 +1,2 @@
<h1 id="sometitle">some title</h1>
<p>Test <strong>bold</strong> and <em>italic</em></p>

View File

@ -0,0 +1,14 @@
var showdown = require('../../.build/showdown.js');
var ext = {
type: 'lang',
regex: /foo/g,
replace: 'bar'
};
showdown.extension('mockextension', function () {
'use strict';
return [ext];
});
module.exports = ext;

View File

@ -49,10 +49,7 @@ function runTests () {
showdown.subParser('makehtml.hashHTMLBlocks')(testMDFile, options, globals);
})
.add('anchors', function () {
showdown.subParser('makehtml.anchors')(testMDFile, options, globals);
})
.add('autoLinks', function () {
showdown.subParser('makehtml.autoLinks')(testMDFile, options, globals);
showdown.subParser('makehtml.links')(testMDFile, options, globals);
})
.add('blockQuotes', function () {
showdown.subParser('makehtml.blockQuotes')(testMDFile, options, globals);

293
test/unit/cli.js Normal file
View File

@ -0,0 +1,293 @@
var fs = require('fs'),
path = require('path'),
chai = require('chai'),
expect = chai.expect,
chaiMatch = require('chai-match'),
execSync = require('child_process').execSync,
spawnSync = require('child_process').spawnSync,
cmd = 'node src/cli/cli.js',
packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
require('sinon');
chai.should();
chai.use(chaiMatch);
/**
* Spawns a CLI process synchrously
* @param {string|null} command
* @param {string[]} args
* @param {{}} [options]
* @returns {{output: *, stdout: string, stderr: string, status: number}}
*/
function spawnCLI (command, args, options) {
'use strict';
var nargs = ['src/cli/cli.js'];
if (command) { nargs.push(command);}
args = nargs.concat(args);
var otp = spawnSync('node', args, options),
stdout = otp.stdout.toString(),
stderr = otp.stderr.toString(),
output = otp.output[0],
status = otp.status;
return {stdout: stdout, stderr: stderr, output: output, status: status};
}
describe('showdown cli', function () {
'use strict';
describe('without commands', function () {
it('should display help if no commands are specified', function () {
var proc = spawnCLI(null, [], {});
proc.status.should.equal(1);
proc.stderr.should.contain('CLI to Showdownjs markdown parser');
proc.stderr.should.contain('Usage:');
proc.stderr.should.contain('Options:');
proc.stderr.should.contain('Commands:');
proc.stdout.should.equal('');
});
describe('-h', function () {
it('should display help', function () {
var proc = spawnCLI(null, ['-h'], {});
proc.status.should.equal(0);
proc.stdout.should.contain('CLI to Showdownjs markdown parser');
proc.stdout.should.contain('Usage:');
proc.stdout.should.contain('Options:');
proc.stdout.should.contain('Commands:');
proc.stderr.should.equal('');
});
});
describe('-v', function () {
it('should display version', function () {
var proc = spawnCLI(null, ['-V'], {});
proc.status.should.equal(0);
proc.stdout.should.match(/^\d{1,2}\.\d{1,3}\.\d{1,3}/);
proc.stdout.should.match(/^(\d{1,2}\.\d{1,3}\.\d{1,3})/).and.capture(0).equals(packageJson.version);
proc.stderr.should.equal('');
});
});
});
describe('makehtml command', function () {
describe('makehtml without flags', function () {
it('should read from stdin and output to stdout', function () {
var proc = spawnCLI('makehtml', [], {
input: '**foo**',
encoding: 'utf-8'
});
proc.status.should.equal(0);
proc.stdout.should.equal('<p><strong>foo</strong></p>');
proc.stderr.should.not.equal('');
});
});
describe('makehtml -p', function () {
it('should enable a flavor', function () {
var proc = spawnCLI('makehtml', ['-p', 'github'], {
input: 'this is a :smile:', // test the emoji option as a proxy
encoding: 'utf-8'
});
proc.status.should.equal(0);
proc.stderr.should.contain('Enabling flavor github...');
proc.stdout.should.equal('<p>this is a 😄</p>');
//'Here in London'.should.match(/(here|there) in (\w+)/i).and.capture(1).equals('London');
});
it('should give an error if a flavor is not recognised', function () {
var proc = spawnCLI('makehtml', ['-p', 'foobar'], {
input: '**foo**',
encoding: 'utf-8'
});
proc.status.should.equal(1);
});
});
describe('makehtml -c', function () {
it('should not parse emoji if config option is not passed', function () {
var proc = spawnCLI('makehtml', [], {
input: 'this is a :smile:',
encoding: 'utf-8'
});
proc.status.should.equal(0);
proc.stderr.should.not.contain('Enabling option emoji');
proc.stdout.should.equal('<p>this is a :smile:</p>');
});
it('should enable a showdown option', function () {
var proc = spawnCLI('makehtml', ['-c', 'emoji'], {
input: 'this is a :smile:',
encoding: 'utf-8'
});
proc.status.should.equal(0);
proc.stderr.should.contain('Enabling option emoji');
proc.stdout.should.equal('<p>this is a 😄</p>');
});
it('should ignore unrecognized options', function () {
var proc = spawnCLI('makehtml', ['-c', 'foobar'], {
input: 'foo',
encoding: 'utf-8'
});
proc.status.should.equal(0);
proc.stderr.should.contain('Enabling option foobar');
proc.stdout.should.equal('<p>foo</p>');
});
});
describe('makehtml -m', function () {
it('should mute information', function () {
var proc = spawnCLI('makehtml', ['-m', '-i'], {input: '**foo**'});
proc.status.should.equal(0);
expect(proc.output).to.be.null; // jshint ignore:line
proc.stdout.should.equal('<p><strong>foo</strong></p>');
proc.stderr.should.equal('');
});
it('should mute everything, even errors', function () {
var proc = spawnCLI('makehtml', ['-m', '-i']);
proc.status.should.equal(1);
expect(proc.output).to.be.null; // jshint ignore:line
proc.stdout.should.equal('');
proc.stderr.should.equal('');
});
it('should not mute parsed html', function () {
var proc = spawnCLI('makehtml', ['-m', '-i'], {
input: '**foo**',
encoding: 'utf-8'
});
proc.status.should.equal(0);
proc.stdout.should.equal('<p><strong>foo</strong></p>');
proc.stderr.should.equal('');
});
});
describe('makehtml -q', function () {
it('should not display information', function () {
var proc = spawnCLI('makehtml', ['-q', '-i'], {input: '**foo**'});
proc.status.should.equal(0);
expect(proc.output).to.be.null; // jshint ignore:line
proc.stdout.should.equal('<p><strong>foo</strong></p>');
proc.stderr.should.match(/^\s*DONE!\s*$/);
});
it('should display errors', function () {
var proc = spawnCLI('makehtml', ['-q', '-i']);
proc.status.should.equal(1);
expect(proc.output).to.be.null; // jshint ignore:line
proc.stdout.should.equal('');
proc.stderr.should.match(/^ERROR:/);
});
it('should not mute parsed html', function () {
var proc = spawnCLI('makehtml', ['-q', '-i'], {
input: '**foo**',
encoding: 'utf-8'
});
proc.status.should.equal(0);
proc.stdout.should.equal('<p><strong>foo</strong></p>');
proc.stderr.should.match(/^\s*DONE!\s*$/);
});
});
describe('makehtml -i -o', function () {
it('should read from stdin and output to stdout', function () {
var proc = spawnCLI('makehtml', ['-i', '-o'], {
input: '**foo**',
encoding: 'utf-8'
});
proc.status.should.equal(0);
proc.stdout.should.equal('<p><strong>foo</strong></p>');
proc.stderr.should.not.equal('');
});
});
describe('makehtml -i <file> -o', function () {
it('should read from a file and output to stdout', function () {
var expectedOtp = fs.readFileSync('test/cli/basic.html', 'utf8').toString().trim(),
proc = spawnCLI('makehtml', ['-i', 'test/cli/basic.md'], {encoding: 'utf-8'});
proc.status.should.equal(0);
proc.stdout.should.equal(expectedOtp);
proc.stderr.should.not.equal('');
});
});
describe('makehtml -i -o <file>', function () {
it('should read from stdin and output to a file', function () {
execSync(cmd + ' makehtml -m -i -o .build/io1.html', {
encoding: 'utf8',
input: '**foo**'
});
var otp = fs.readFileSync('.build/io1.html', 'utf8').toString().trim(),
expectedOtp = '<p><strong>foo</strong></p>';
otp.trim().should.equal(expectedOtp);
});
});
describe('makehtml -i <file> -o <file>', function () {
it('should read from a file and output to a file', function () {
var expectedOtp = fs.readFileSync('test/cli/basic.html', 'utf8').toString().trim(),
proc = spawnCLI('makehtml', ['-i', 'test/cli/basic.md', '-o', '.build/io2.html'], {encoding: 'utf-8'}),
otp = fs.readFileSync('.build/io2.html', 'utf8').toString().trim();
otp.trim().should.equal(expectedOtp);
proc.stdout.should.not.equal(expectedOtp);
proc.stderr.should.equal('');
proc.status.should.equal(0);
});
});
describe('makehtml -a', function () {
it('should read from stdin and append to a file', function () {
fs.writeFileSync('.build/io3.html', '<p>foo</p>');
var expectedOtp = '<p>foo</p><p><strong>foo</strong></p>',
proc = spawnCLI('makehtml', ['-i', '-o', '.build/io3.html', '-a'], {
encoding: 'utf8',
input: '**foo**'
}),
otp = fs.readFileSync('.build/io3.html', 'utf8').toString().trim();
proc.status.should.equal(0);
otp.trim().should.equal(expectedOtp);
// since the output is to a file, messages are logged to stdout
proc.stdout.should.not.equal(expectedOtp);
// stderr should be empty
proc.stderr.should.equal('');
});
it('should ignore -a flag if -o <file> is missing', function () {
var expectedOtp = '<p><strong>foo</strong></p>',
proc = spawnCLI('makehtml', ['-a'], {encoding: 'utf8', input: '**foo**'});
proc.status.should.equal(0);
proc.stderr.should.not.equal('');
proc.stdout.should.equal(expectedOtp);
});
});
describe('makehtml -e', function () {
it('should load the extension', function () {
var expectedOtp = '<p><strong>bar</strong></p>',
extPath = path.resolve(__dirname + '/../mocks/mock-extension.js'),
proc = spawnCLI('makehtml', ['-i', '-o', '-e', extPath], {
encoding: 'utf8',
input: '**foo**'
});
proc.status.should.equal(0, 'Process exited with error state');
proc.stdout.trim().should.equal(expectedOtp);
});
});
});
});

View File

@ -0,0 +1,25 @@
/**
* Created by Estevao on 15-01-2015.
*/
describe('showdown.Converter', function () {
'use strict';
require('source-map-support').install();
require('chai').should();
var jsdom = require('jsdom'),
document = new jsdom.JSDOM('', {}).window.document, // jshint ignore:line
showdown = require('../../.build/showdown.js');
describe('makeMarkdown()', function () {
var converter = new showdown.Converter();
it('should parse a simple html string', function () {
var html = '<a href="/somefoo.html">a link</a>\n';
var md = '[a link](</somefoo.html>)';
converter.makeMarkdown(html, document).should.equal(md);
});
});
});

View File

@ -3,6 +3,7 @@ require('chai').should();
var expect = require('chai').expect,
showdown = require('../../.build/showdown.js');
describe('showdown.options', function () {
'use strict';
@ -34,21 +35,37 @@ describe('showdown.extension()', function () {
return extObjMock;
};
describe('should register', function () {
it('an extension object', function () {
describe('file loading', function () {
beforeEach(function () {
this.extension = require('../mocks/mock-extension');
});
it('should register an extension from a file', function () {
showdown.extension('mockextension').should.be.an('array');
showdown.extension('mockextension').should.eql([this.extension]);
});
afterEach(function () {
showdown.resetExtensions();
});
});
describe('objects', function () {
it('should register an extension object', function () {
showdown.extension('foo', extObjMock);
showdown.extension('foo').should.eql([extObjMock]);
showdown.resetExtensions();
});
it('an extension function', function () {
showdown.extension('foo', extObjFunc);
showdown.extension('foo').should.eql([extObjMock]);
showdown.resetExtensions();
it('should register an extension function', function () {
showdown.extension('bar', extObjFunc);
showdown.extension('bar').should.eql([extObjMock]);
});
it('a listener extension', function () {
showdown.extension('foo', {
it('should register a listener extension', function () {
showdown.extension('baz', {
type: 'listener',
listeners: {
foo: function (name, txt) {
@ -56,19 +73,16 @@ describe('showdown.extension()', function () {
}
}
});
showdown.resetExtensions();
});
});
describe('should refuse to register', function () {
it('a generic object', function () {
it('should refuse to register a generic object', function () {
var fn = function () {
showdown.extension('foo', {});
};
expect(fn).to.throw();
});
it('an extension with invalid type', function () {
it('should refuse to register an extension with invalid type', function () {
var fn = function () {
showdown.extension('foo', {
type: 'foo'
@ -77,7 +91,7 @@ describe('showdown.extension()', function () {
expect(fn).to.throw(/type .+? is not recognized\. Valid values: "lang\/language", "output\/html" or "listener"/);
});
it('an extension without regex or filter', function () {
it('should refuse to register an extension without regex or filter', function () {
var fn = function () {
showdown.extension('foo', {
type: 'lang'
@ -86,7 +100,7 @@ describe('showdown.extension()', function () {
expect(fn).to.throw(/extensions must define either a "regex" property or a "filter" method/);
});
it('a listener extension without a listeners property', function () {
it('should refuse to register a listener extension without a listeners property', function () {
var fn = function () {
showdown.extension('foo', {
type: 'listener'
@ -94,7 +108,13 @@ describe('showdown.extension()', function () {
};
expect(fn).to.throw(/Extensions of type "listener" must have a property called "listeners"/);
});
afterEach(function () {
showdown.resetExtensions();
});
});
});
describe('showdown.getAllExtensions()', function () {