commonmark
Advanced tools
Comparing version
@@ -0,1 +1,62 @@ | ||
[0.29.0] | ||
* Update spec to 0.29. | ||
* Fix parsing of setext headers after reference link definitions. | ||
* Fix code span normalization to conform to spec change. | ||
* Allow empty destinations in link refs. See commonmark/commonmark#172. | ||
* Update link destination parsing. | ||
* dingus: add dependency version requirements (#159, Vas Sudanagunta). | ||
Dingus was rendering incorrectly with Bootstrap 4. Added a bower.json | ||
which requires Bootstrap, jQuery and Lodash with major version equal | ||
to what's currently live. Likewise the minimum patch version. | ||
* package.json: Add version for bower in devDependencies. | ||
* package.json - use `^` operator for versions. | ||
* Allow internal delim runs to match if both have lengths that | ||
are multiples of 3. See commonmark/commonmark#528. | ||
* Remove now unused 'preserve_entities' option on escapeXml. | ||
This was formerly used (incorrectly) in the HTML renderer. | ||
It isn't needed any more. [API change] | ||
* html renderer: Don't preserve entities when rendering | ||
href, src, title, info string. This gives rise to double-encoding errors, | ||
when the original markdown is e.g. `:`, since the commonmark | ||
reader already unescapes entities. Thanks to Sebastiaan Knijnenburg for | ||
noticing this. | ||
* More efficient checking for loose lists. | ||
This fixes a case like commonmark/cmark#284. | ||
* Disallow unescaped `(` in parenthesized link title. | ||
* Add pathological test (commonmark/cmark#285). | ||
* Comment out failing pathological test for now. | ||
* Add pathological tests for #157. | ||
* Fix two exponential regex backtracking vulnerabilities (#157, | ||
Anders Kaseorg). ESCAPED_CHAR already matches `\\`, so matching it again | ||
in another alternative was causing exponential complexity explosion. | ||
This makes the following behavior changes: | ||
`[foo\\\]` is no longer incorrectly accepted as a link reference. | ||
`<foo\>` is no longer incorrectly accepted as an angle-bracketed | ||
link destination. | ||
* package.json: require lodash >= 4.17.11. | ||
* Require cached-path-relative >= 1.0.2. | ||
This fixes a security vulnerability, but it's only | ||
in the dev dependencies. | ||
* Update fenced block parsing for spec change. | ||
* Require space before title in reference link. | ||
See commonmark/cmark#263. | ||
* Update code span normalization for spec change. | ||
* Removed meta from list of block tags. See commonmark/CommonMark#527. | ||
* make dist: ensure that comment line is included in dist files (#144). | ||
Also change URL to CommonMark/commonmark.js. | ||
* Use local development dependencies (#142, Lynn Kirby). | ||
Packages used during development are now listed in devDependencies of | ||
package.json. Makefiles are updated to use those local versions. | ||
References to manually installing packages are removed from README.md | ||
and bench/bench.js. The package-lock.json file used in newer NPM | ||
versions is also added. | ||
* Allow spaces in pointy-bracket link destinations. | ||
* Adjust max length for decimal/numeric entities. | ||
See commonmark/CommonMark#487. | ||
* Don't allow escaped spaces in link destination. | ||
Closes commonmark/CommonMark#493. | ||
* Don't allow list items that are indented >= 4 spaces. | ||
See commonmark/CommonMark#497. | ||
[0.28.1] | ||
@@ -2,0 +63,0 @@ |
@@ -26,3 +26,3 @@ "use strict"; | ||
/^<!\[CDATA\[/, | ||
/^<[/]?(?:address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[123456]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|section|source|title|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul)(?:\s|[/]?[>]|$)/i, | ||
/^<[/]?(?:address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[123456]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|nav|noframes|ol|optgroup|option|p|param|section|source|title|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul)(?:\s|[/]?[>]|$)/i, | ||
new RegExp('^(?:' + OPENTAG + '|' + CLOSETAG + ')\\s*$', 'i') | ||
@@ -52,3 +52,3 @@ ]; | ||
var reCodeFence = /^`{3,}(?!.*`)|^~{3,}(?!.*~)/; | ||
var reCodeFence = /^`{3,}(?!.*`)|^~{3,}/; | ||
@@ -90,5 +90,8 @@ var reClosingCodeFence = /^(?:`{3,}|~{3,})(?= *$)/; | ||
var t = block.type; | ||
if (t === 'list' || t === 'item') { | ||
if (!block._lastLineChecked && | ||
(t === 'list' || t === 'item')) { | ||
block._lastLineChecked = true; | ||
block = block._lastChild; | ||
} else { | ||
block._lastLineChecked = true; | ||
break; | ||
@@ -143,2 +146,5 @@ } | ||
markerOffset: parser.indent }; | ||
if (parser.indent >= 4) { | ||
return null; | ||
} | ||
if ((match = rest.match(reBulletListMarker))) { | ||
@@ -498,10 +504,23 @@ data.type = 'bullet'; | ||
parser.closeUnmatchedBlocks(); | ||
var heading = new Node('heading', container.sourcepos); | ||
heading.level = match[0][0] === '=' ? 1 : 2; | ||
heading._string_content = container._string_content; | ||
container.insertAfter(heading); | ||
container.unlink(); | ||
parser.tip = heading; | ||
parser.advanceOffset(parser.currentLine.length - parser.offset, false); | ||
return 2; | ||
// resolve reference link definitiosn | ||
var pos; | ||
while (peek(container._string_content, 0) === C_OPEN_BRACKET && | ||
(pos = | ||
parser.inlineParser.parseReference( | ||
container._string_content, parser.refmap))) { | ||
container._string_content = | ||
container._string_content.slice(pos); | ||
} | ||
if (container._string_content.length > 0) { | ||
var heading = new Node('heading', container.sourcepos); | ||
heading.level = match[0][0] === '=' ? 1 : 2; | ||
heading._string_content = container._string_content; | ||
container.insertAfter(heading); | ||
container.unlink(); | ||
parser.tip = heading; | ||
parser.advanceOffset(parser.currentLine.length - parser.offset, false); | ||
return 2; | ||
} else { | ||
return 0; | ||
} | ||
} else { | ||
@@ -508,0 +527,0 @@ return 0; |
@@ -10,3 +10,3 @@ "use strict"; | ||
var ENTITY = "&(?:#x[a-f0-9]{1,8}|#[0-9]{1,8}|[a-z][a-z0-9]{1,31});"; | ||
var ENTITY = "&(?:#x[a-f0-9]{1,6}|#[0-9]{1,7}|[a-z][a-z0-9]{1,31});"; | ||
@@ -41,4 +41,2 @@ var TAGNAME = '[A-Za-z][A-Za-z0-9-]*'; | ||
var reXmlSpecialOrEntity = new RegExp(ENTITY + '|' + XMLSPECIAL, 'gi'); | ||
var unescapeChar = function(s) { | ||
@@ -85,9 +83,5 @@ if (s.charCodeAt(0) === C_BACKSLASH) { | ||
var escapeXml = function(s, preserve_entities) { | ||
var escapeXml = function(s) { | ||
if (reXmlSpecial.test(s)) { | ||
if (preserve_entities) { | ||
return s.replace(reXmlSpecialOrEntity, replaceUnsafeChar); | ||
} else { | ||
return s.replace(reXmlSpecial, replaceUnsafeChar); | ||
} | ||
return s.replace(reXmlSpecial, replaceUnsafeChar); | ||
} else { | ||
@@ -94,0 +88,0 @@ return s; |
@@ -46,6 +46,5 @@ "use strict"; | ||
'|' + | ||
'\\((' + ESCAPED_CHAR + '|[^)\\x00])*\\))'); | ||
'\\((' + ESCAPED_CHAR + '|[^()\\x00])*\\))'); | ||
var reLinkDestinationBraces = new RegExp( | ||
'^(?:[<](?:[^ <>\\t\\n\\\\\\x00]' + '|' + ESCAPED_CHAR + '|' + '\\\\)*[>])'); | ||
var reLinkDestinationBraces = /^(?:<(?:[^<>\n\\\x00]|\\.)*>)/; | ||
@@ -82,4 +81,3 @@ var reEscapable = new RegExp('^' + ESCAPABLE); | ||
var reLinkLabel = new RegExp('^\\[(?:[^\\\\\\[\\]]|' + ESCAPED_CHAR + | ||
'|\\\\){0,1000}\\]'); | ||
var reLinkLabel = /^\[(?:[^\\\[\]]|\\.){0,1000}\]/; | ||
@@ -143,8 +141,17 @@ // Matches a string of non-special characters. | ||
var node; | ||
var contents; | ||
while ((matched = this.match(reTicks)) !== null) { | ||
if (matched === ticks) { | ||
node = new Node('code'); | ||
node._literal = this.subject.slice(afterOpenTicks, | ||
contents = this.subject.slice(afterOpenTicks, | ||
this.pos - ticks.length) | ||
.trim().replace(reWhitespace, ' '); | ||
.replace(/\n/gm, ' '); | ||
if (contents.length > 0 && | ||
contents.match(/[^ ]/) !== null && | ||
contents[0] == ' ' && | ||
contents[contents.length - 1] == ' ') { | ||
node._literal = contents.slice(1, contents.length - 1); | ||
} else { | ||
node._literal = contents; | ||
} | ||
block.appendChild(node); | ||
@@ -370,3 +377,4 @@ return true; | ||
odd_match = (closer.can_open || opener.can_close) && | ||
(opener.origdelims + closer.origdelims) % 3 === 0; | ||
closer.origdelims % 3 !== 0 && | ||
(opener.origdelims + closer.origdelims) % 3 === 0; | ||
if (opener.cc === closer.cc && opener.can_open && !odd_match) { | ||
@@ -487,2 +495,5 @@ opener_found = true; | ||
if (res === null) { | ||
if (this.peek() === C_LESSTHAN) { | ||
return null; | ||
} | ||
// TODO handrolled parser; res should be null or the string | ||
@@ -493,3 +504,4 @@ var savepos = this.pos; | ||
while ((c = this.peek()) !== -1) { | ||
if (c === C_BACKSLASH) { | ||
if (c === C_BACKSLASH | ||
&& reEscapable.test(this.subject.charAt(this.pos + 1))) { | ||
this.pos += 1; | ||
@@ -515,2 +527,5 @@ if (this.peek() !== -1) { | ||
} | ||
if (this.pos === savepos && c !== C_CLOSE_PAREN) { | ||
return null; | ||
} | ||
res = this.subject.substr(savepos, this.pos - savepos); | ||
@@ -526,5 +541,3 @@ return normalizeURI(unescapeString(res)); | ||
var m = this.match(reLinkLabel); | ||
// Note: our regex will allow something of form [..\]; | ||
// we disallow it here rather than using lookahead in the regex: | ||
if (m === null || m.length > 1001 || /[^\\]\\\]$/.exec(m)) { | ||
if (m === null || m.length > 1001) { | ||
return 0; | ||
@@ -804,3 +817,3 @@ } else { | ||
dest = this.parseLinkDestination(); | ||
if (dest === null || dest.length === 0) { | ||
if (dest === null) { | ||
this.pos = startpos; | ||
@@ -812,3 +825,5 @@ return 0; | ||
this.spnl(); | ||
title = this.parseLinkTitle(); | ||
if (this.pos !== beforetitle) { | ||
title = this.parseLinkTitle(); | ||
} | ||
if (title === null) { | ||
@@ -815,0 +830,0 @@ title = ''; |
@@ -79,2 +79,3 @@ "use strict"; | ||
this._lastLineBlank = false; | ||
this._lastLineChecked = false; | ||
this._open = true; | ||
@@ -81,0 +82,0 @@ this._string_content = null; |
@@ -65,6 +65,6 @@ "use strict"; | ||
if (!(this.options.safe && potentiallyUnsafe(node.destination))) { | ||
attrs.push(['href', this.esc(node.destination, true)]); | ||
attrs.push(['href', this.esc(node.destination, false)]); | ||
} | ||
if (node.title) { | ||
attrs.push(['title', this.esc(node.title, true)]); | ||
attrs.push(['title', this.esc(node.title, false)]); | ||
} | ||
@@ -83,3 +83,3 @@ this.tag('a', attrs); | ||
} else { | ||
this.lit('<img src="' + this.esc(node.destination, true) + | ||
this.lit('<img src="' + this.esc(node.destination, false) + | ||
'" alt="'); | ||
@@ -93,3 +93,3 @@ } | ||
if (node.title) { | ||
this.lit('" title="' + this.esc(node.title, true)); | ||
this.lit('" title="' + this.esc(node.title, false)); | ||
} | ||
@@ -149,3 +149,3 @@ this.lit('" />'); | ||
if (info_words.length > 0 && info_words[0].length > 0) { | ||
attrs.push(['class', 'language-' + this.esc(info_words[0], true)]); | ||
attrs.push(['class', 'language-' + this.esc(info_words[0], false)]); | ||
} | ||
@@ -152,0 +152,0 @@ this.cr(); |
@@ -1,17 +0,25 @@ | ||
{ "name": "commonmark", | ||
{ | ||
"name": "commonmark", | ||
"description": "a strongly specified, highly compatible variant of Markdown", | ||
"version": "0.28.1", | ||
"version": "0.29.0", | ||
"homepage": "http://commonmark.org", | ||
"keywords": | ||
[ "markdown", | ||
"commonmark", | ||
"md", | ||
"stmd" ], | ||
"keywords": [ | ||
"markdown", | ||
"commonmark", | ||
"md", | ||
"stmd" | ||
], | ||
"repository": "jgm/commonmark.js", | ||
"author": "John MacFarlane", | ||
"bugs": { "url": "https://github.com/jgm/commonmark.js/issues" }, | ||
"bugs": { | ||
"url": "https://github.com/jgm/commonmark.js/issues" | ||
}, | ||
"license": "BSD-2-Clause", | ||
"main": "./lib/index.js", | ||
"bin": { "commonmark": "./bin/commonmark" }, | ||
"scripts": { "test": "node ./test/test.js" }, | ||
"bin": { | ||
"commonmark": "./bin/commonmark" | ||
}, | ||
"scripts": { | ||
"test": "node ./test/test.js" | ||
}, | ||
"dependencies": { | ||
@@ -24,7 +32,20 @@ "entities": "~ 1.1.1", | ||
"directories": { | ||
"lib": "./lib" | ||
"lib": "./lib" | ||
}, | ||
"engines": { | ||
"node": "*" | ||
"node": "*" | ||
}, | ||
"devDependencies": { | ||
"benchmark": "^2.1.4", | ||
"bower": "^1.8.8", | ||
"browserify": "^16.2.2", | ||
"eslint": "^4.19.1", | ||
"http-server": "^0.11.1", | ||
"markdown-it": "^8.4.1", | ||
"marked": "^0.4.0", | ||
"showdown": "^1.8.6", | ||
"uglify-js": "^3.4.0", | ||
"cached-path-relative": "^1.0.2", | ||
"lodash": "^4.17.11" | ||
} | ||
} |
commonmark.js | ||
============= | ||
[](https://travis-ci.org/jgm/commonmark.js) | ||
[](https://travis-ci.org/commonmark/commonmark.js) | ||
[](https://www.npmjs.org/package/commonmark) | ||
@@ -35,12 +35,20 @@ | ||
For client-side use, you can do `make dist` to produce | ||
a standalone JavaScript file `js/dist/commonmark.js`, | ||
suitable for linking into a web page, or fetch the latest | ||
from | ||
For client-side use, fetch the latest from | ||
<https://raw.githubusercontent.com/jgm/commonmark.js/master/dist/commonmark.js>, | ||
or `bower install commonmark`. | ||
Building | ||
-------- | ||
Make sure to fetch dependencies with: | ||
npm install | ||
To build standalone JavaScript files (`dist/commonmark.js` and | ||
`dist/commonmark.min.js`): | ||
make dist | ||
To run tests for the JavaScript library: | ||
npm install # if needed to fetch dependencies | ||
make test | ||
@@ -50,3 +58,2 @@ | ||
npm install benchmark showdown marked markdown-it | ||
make bench | ||
@@ -59,3 +66,2 @@ | ||
Usage | ||
@@ -84,13 +90,17 @@ ----- | ||
``` js | ||
var reader = new commonmark.Parser({smart: true}); | ||
var writer = new commonmark.HtmlRenderer({sourcepos: true}); | ||
``` | ||
The following options are currently supported: | ||
`Parser` currently supports the following: | ||
- `smart`: if `true`, straight quotes will be made curly, `--` will | ||
be changed to an en dash, `---` will be changed to an em dash, and | ||
`...` will be changed to ellipses. | ||
Both `HtmlRenderer` and `XmlRenderer` (see below) support these options: | ||
- `sourcepos`: if `true`, source position information for block-level | ||
elements will be rendered in the `data-sourcepos` attribute (for | ||
HTML) or the `sourcepos` attribute (for XML). | ||
- `smart`: if `true`, straight quotes will be made curly, `--` will | ||
be changed to an en dash, `---` will be changed to an em dash, and | ||
`...` will be changed to ellipses. | ||
- `safe`: if `true`, raw HTML will not be passed through to HTML | ||
@@ -102,3 +112,6 @@ output (it will be replaced by comments), and potentially unsafe | ||
- `softbreak`: specify raw string to be used for a softbreak. | ||
- `esc`: specify a function to be used to escape strings. | ||
- `esc`: specify a function to be used to escape strings. Its | ||
first argument is the string to be escaped, the second argument | ||
is a boolean indicating whether to preserves entities in that | ||
string. | ||
@@ -117,8 +130,3 @@ For example, to make soft breaks render as hard breaks in HTML: | ||
To override `esc`, pass it a function with two parameters: | ||
the first is the string to be escaped, the second is a boolean | ||
that is `true` if entities in the string to be escaped should | ||
be preserved. | ||
In addition to the `HtmlRenderer`, there is an `XmlRenderer`, which | ||
`XmlRenderer` serves as an alternative to `HtmlRenderer` and | ||
will produce an XML representation of the AST: | ||
@@ -273,3 +281,3 @@ | ||
Here are some focused benchmarks of four JavaScript libraries | ||
(using versions available on 24 Jan 2015). They test performance | ||
(using versions available on 24 Jan 2015). They test performance | ||
on different kinds of Markdown texts. (Most of these samples | ||
@@ -339,9 +347,6 @@ are taken from the | ||
To generate this table, | ||
To generate this table: | ||
npm install showdown marked markdown-it benchmark | ||
make bench-detailed | ||
Authors | ||
@@ -348,0 +353,0 @@ ------- |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
434091
1.27%6268
1%353
1.44%11
Infinity%