diff --git a/lib/marked.js b/lib/marked.js index 79478498c9..d635f2449e 100644 --- a/lib/marked.js +++ b/lib/marked.js @@ -605,9 +605,8 @@ inline.pedantic = merge({}, inline.normal, { inline.gfm = merge({}, inline.normal, { escape: edit(inline.escape).replace('])', '~|])').getRegex(), - url: edit(/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/) - .replace('email', inline._email) - .getRegex(), + _extended_email: /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/, + url: /^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/, _backpedal: /(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/, del: /^~+(?=\S)([\s\S]*?\S)~+/, text: edit(inline.text) @@ -616,6 +615,9 @@ inline.gfm = merge({}, inline.normal, { .getRegex() }); +inline.gfm.url = edit(inline.gfm.url) + .replace('email', inline.gfm._extended_email) + .getRegex(); /** * GFM + Line Breaks Inline Grammar */ @@ -703,15 +705,15 @@ InlineLexer.prototype.output = function(src) { // url (gfm) if (!this.inLink && (cap = this.rules.url.exec(src))) { - do { - prevCapZero = cap[0]; - cap[0] = this.rules._backpedal.exec(cap[0])[0]; - } while (prevCapZero !== cap[0]); - src = src.substring(cap[0].length); if (cap[2] === '@') { text = escape(cap[0]); href = 'mailto:' + text; } else { + // do extended autolink path validation + do { + prevCapZero = cap[0]; + cap[0] = this.rules._backpedal.exec(cap[0])[0]; + } while (prevCapZero !== cap[0]); text = escape(cap[0]); if (cap[1] === 'www.') { href = 'http://' + text; @@ -719,6 +721,7 @@ InlineLexer.prototype.output = function(src) { href = text; } } + src = src.substring(cap[0].length); out += this.renderer.link(href, null, text); continue; } diff --git a/test/specs/marked/marked-spec.js b/test/specs/marked/marked-spec.js index 8bc52ec35b..c4f2761551 100644 --- a/test/specs/marked/marked-spec.js +++ b/test/specs/marked/marked-spec.js @@ -49,7 +49,7 @@ describe('Marked Autolinks', function() { describe('Marked Code spans', function() { var section = 'Code spans'; - var shouldPassButFails = [1]; + var shouldPassButFails = []; var willNotBeAttemptedByCoreTeam = []; diff --git a/test/specs/marked/marked.json b/test/specs/marked/marked.json index 1cb3a2a8dd..5332e494d8 100644 --- a/test/specs/marked/marked.json +++ b/test/specs/marked/marked.json @@ -1,22 +1,4 @@ [ - { - "section": "Autolinks", - "markdown": "(See https://www.example.com/fhqwhgads.)", - "html": "

(See https://www.example.com/fhqwhgads.)

", - "example": 10 - }, - { - "section": "Autolinks", - "markdown": "((http://foo.com))", - "html": "

((http://foo.com))

", - "example": 11 - }, - { - "section": "Autolinks", - "markdown": "((http://foo.com.))", - "html": "

((http://foo.com.))

", - "example": 12 - }, { "section": "Code spans", "markdown": "`someone@example.com`", @@ -76,5 +58,35 @@ "markdown": "Link: [constructor][].\n\n[constructor]: https://example.org/", "html": "

Link: constructor.

", "example": 10 + }, + { + "section": "Autolinks", + "markdown": "(See https://www.example.com/fhqwhgads.)", + "html": "

(See https://www.example.com/fhqwhgads.)

", + "example": 11 + }, + { + "section": "Autolinks", + "markdown": "((http://foo.com))", + "html": "

((http://foo.com))

", + "example": 12 + }, + { + "section": "Autolinks", + "markdown": "((http://foo.com.))", + "html": "

((http://foo.com.))

", + "example": 13 + }, + { + "section": "Autolinks", + "markdown": "~~hello@email.com~~", + "html": "

hello@email.com

", + "example": 1307 + }, + { + "section": "Autolinks", + "markdown": "**me@example.com**", + "html": "

me@example.com

", + "example": 1327 } -] +] \ No newline at end of file