Skip to content

[commonmark] Make link definitions commonmark compliant #1018

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jan 20, 2018
Merged
35 changes: 23 additions & 12 deletions lib/marked.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,19 @@ var block = {
blockquote: /^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,
list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
html: /^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,
def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,
def: /^ {0,3}\[(label)\]: *\n? *<?([^\s>]+)>?(?:(?: +\n? *| *\n *)(title))? *(?:\n+|$)/,
table: noop,
paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag))+)\n*/,
text: /^[^\n]+/
};

block._label = /(?:\\[\[\]]|[^\[\]])+/;
block._title = /(?:"(?:\\"|[^"])*"|'\n?(?:[^'\n]+\n?)*'|\([^()]*\))/;
block.def = replace(block.def)
('label', block._label)
('title', block._title)
();

block.bullet = /(?:[*+-]|\d+\.)/;
block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;
block.item = replace(block.item, 'gm')
Expand Down Expand Up @@ -62,7 +69,6 @@ block.paragraph = replace(block.paragraph)
('lheading', block.lheading)
('blockquote', block.blockquote)
('tag', '<' + block._tag)
('def', block.def)
();

/**
Expand Down Expand Up @@ -148,7 +154,7 @@ Lexer.prototype.lex = function(src) {
* Lexing
*/

Lexer.prototype.token = function(src, top, bq) {
Lexer.prototype.token = function(src, top) {
var src = src.replace(/^ +$/gm, '')
, next
, loose
Expand All @@ -158,6 +164,7 @@ Lexer.prototype.token = function(src, top, bq) {
, item
, space
, i
, tag
, l;

while (src) {
Expand Down Expand Up @@ -271,7 +278,7 @@ Lexer.prototype.token = function(src, top, bq) {
// Pass `top` to keep the current
// "toplevel" state. This is exactly
// how markdown.pl works.
this.token(cap, top, true);
this.token(cap, top);

this.tokens.push({
type: 'blockquote_end'
Expand Down Expand Up @@ -340,7 +347,7 @@ Lexer.prototype.token = function(src, top, bq) {
});

// Recurse.
this.token(item, false, bq);
this.token(item, false);

this.tokens.push({
type: 'list_item_end'
Expand Down Expand Up @@ -369,12 +376,16 @@ Lexer.prototype.token = function(src, top, bq) {
}

// def
if ((!bq && top) && (cap = this.rules.def.exec(src))) {
if (top && (cap = this.rules.def.exec(src))) {
src = src.substring(cap[0].length);
this.tokens.links[cap[1].toLowerCase()] = {
href: cap[2],
title: cap[3]
};
if (cap[3]) cap[3] = cap[3].substring(1,cap[3].length-1);
tag = cap[1].toLowerCase();
if (!this.tokens.links[tag]) {
this.tokens.links[tag] = {
href: cap[2],
title: cap[3]
};
}
continue;
}

Expand Down Expand Up @@ -455,7 +466,7 @@ var inline = {
tag: /^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^<'">])*?>/,
link: /^!?\[(inside)\]\(href\)/,
reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/,
nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,
nolink: /^!?\[((?:\[[^\]]*\]|\\[\[\]]|[^\[\]])*)\]/,
strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,
em: /^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
code: /^(`+)([\s\S]*?[^`])\1(?!`)/,
Expand Down
115 changes: 115 additions & 0 deletions test/new/cm_link_defs.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<h3 id="example-159">Example 159</h3>

<p><a href="/url" title="title">foo159</a></p>

<h3 id="example-160">Example 160</h3>

<p><a href="/url" title="the title">foo160</a></p>

<h3 id="example-161">Example 161</h3>

<p><a href="my_(url)" title="title (with parens)">Foo161*bar]</a></p>

<h3 id="example-162">Example 162</h3>

<p><a href="my%20url" title="title">Foo162 bar</a></p>

<h3 id="example-163">Example 163</h3>

<p><a href="/url" title="
title
line1
line2
">foo163</a></p>

<h3 id="example-164">Example 164</h3>

<p>[foo164]: /url &#39;title</p>
<p>with blank line&#39;</p>
<p>[foo164]</p>

<h3 id="example-165">Example 165</h3>

<p><a href="/url">foo165</a></p>

<h3 id="example-166">Example 166</h3>

<p>[foo166]:</p>
<p>[foo166]</p>

<h3 id="example-167">Example 167</h3>

<pre><code>[foo167]: /url\bar\*baz &quot;foo\&quot;bar\baz&quot;

[foo167]

should render to

&lt;p&gt;&lt;a href=&quot;/url%5Cbar*baz&quot; title=&quot;foo&amp;quot;bar\baz&quot;&gt;foo167&lt;/a&gt;&lt;/p&gt;</code></pre>

<h3 id="example-168">Example 168</h3>

<p><a href="url">foo168</a></p>

<h3 id="example-169">Example 169</h3>

<p><a href="first">foo169</a></p>

<h3 id="example-170">Example 170</h3>

<p><a href="/url">Foo170</a></p>

<h3 id="example-171">Example 171</h3>

<p><a href="/φου">αγω</a></p>

<h3 id="example-172">Example 172</h3>

<h3 id="example-173">Example 173</h3>

<p>bar</p>

<h3 id="example-174">Example 174</h3>

<p>[foo174]: /url &quot;title&quot; ok</p>

<h3 id="example-175">Example 175</h3>

<p>&quot;title&quot; ok</p>

<h3 id="example-176">Example 176</h3>

<pre><code>[foo176]: /url &quot;title&quot;
</code></pre>
<p>[foo176]</p>

<h3 id="example-177">Example 177</h3>

<pre><code>[foo177]: /url
</code></pre>
<p>[foo177]</p>

<h3 id="example-178">Example 178</h3>

<p>Foo
[bar178]: /baz</p>
<p>[bar178]</p>

<h3 id="example-179">Example 179</h3>

<h1 id="-foo179-"><a href="/url">Foo179</a></h1>
<blockquote>
<p>bar</p>
</blockquote>

<h3 id="example-180">Example 180</h3>

<p><a href="/foo-url" title="foo">foo180</a>,
<a href="/bar-url" title="bar">bar180</a>,
<a href="/baz-url">baz180</a></p>

<h3 id="example-181">Example 181</h3>

<p><a href="/url">foo181</a></p>
<blockquote>
</blockquote>
157 changes: 157 additions & 0 deletions test/new/cm_link_defs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
### Example 159

[foo159]: /url "title"

[foo159]

### Example 160

[foo160]:
/url
'the title'

[foo160]

### Example 161

[Foo161*bar\]]:my_(url) 'title (with parens)'

[Foo161*bar\]]

### Example 162

[Foo162 bar]:
<my%20url>
'title'

[Foo162 bar]

### Example 163

[foo163]: /url '
title
line1
line2
'

[foo163]

### Example 164

[foo164]: /url 'title

with blank line'

[foo164]

### Example 165

[foo165]:
/url

[foo165]

### Example 166

[foo166]:

[foo166]

### Example 167

[foo167]: /url\bar\*baz "foo\"bar\baz"

[foo167]

should render to

<p><a href="/url%5Cbar*baz" title="foo&quot;bar\baz">foo167</a></p>

### Example 168

[foo168]

[foo168]: url

### Example 169

[foo169]

[foo169]: first
[foo169]: second

### Example 170

[FOO170]: /url

[Foo170]

### Example 171

[ΑΓΩ]: /φου

[αγω]

### Example 172

[foo172]: /url

### Example 173

[
foo173
]: /url
bar

### Example 174

[foo174]: /url "title" ok

### Example 175

[foo175]: /url
"title" ok

### Example 176

[foo176]: /url "title"

[foo176]

### Example 177

```
[foo177]: /url
```

[foo177]

### Example 178

Foo
[bar178]: /baz

[bar178]

### Example 179

# [Foo179]
[foo179]: /url
> bar

### Example 180

[foo180]: /foo-url "foo"
[bar180]: /bar-url
"bar"
[baz180]: /baz-url

[foo180],
[bar180],
[baz180]

### Example 181

[foo181]

> [foo181]: /url