Skip to content

Commit b9ec6fd

Browse files
Markdown: Improved URLs (#1955)
This fixes the known issue that inline styles (bold, italic, strike) break URLs. Inline styles are now properly highlighted inside URLs.
1 parent d58d2ae commit b9ec6fd

File tree

7 files changed

+179
-32
lines changed

7 files changed

+179
-32
lines changed

components/prism-markdown.js

+15-9
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
(function (Prism) {
22

33
// Allow only one line break
4-
var inner = /\\.|[^\\\n\r_]|(?:\r?\n|\r)(?!\r?\n|\r)/.source;
4+
var inner = /(?:\\.|[^\\\n\r]|(?:\r?\n|\r)(?!\r?\n|\r))/.source;
55

66
/**
77
* This function is intended for the creation of the bold or italic pattern.
@@ -124,7 +124,7 @@
124124
// __strong__
125125

126126
// allow one nested instance of italic text using the same delimiter
127-
pattern: createInline(/__(?:<inner>|_(?:<inner>)+_)+__/.source, true),
127+
pattern: createInline(/__(?:(?!_)<inner>|_(?:(?!_)<inner>)+_)+__/.source, true),
128128
lookbehind: true,
129129
greedy: true,
130130
inside: {
@@ -141,7 +141,7 @@
141141
// _em_
142142

143143
// allow one nested instance of bold text using the same delimiter
144-
pattern: createInline(/_(?:<inner>|__(?:<inner>)+__)+_/.source, true),
144+
pattern: createInline(/_(?:(?!_)<inner>|__(?:(?!_)<inner>)+__)+_/.source, true),
145145
lookbehind: true,
146146
greedy: true,
147147
inside: {
@@ -156,9 +156,7 @@
156156
'strike': {
157157
// ~~strike through~~
158158
// ~strike~
159-
160-
// extra _ is because the inner pattern intentionally doesn't include it because of bold and italic
161-
pattern: createInline(/(~~?)(?:<inner>|_)+?\2/.source, false),
159+
pattern: createInline(/(~~?)(?:(?!~)<inner>)+?\2/.source, false),
162160
lookbehind: true,
163161
greedy: true,
164162
inside: {
@@ -172,21 +170,29 @@
172170
},
173171
'url': {
174172
// [example](http://example.com "Optional title")
173+
// [example][id]
175174
// [example] [id]
176-
pattern: /!?\[[^\]]+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)| ?\[[^\]\n]*\])/,
175+
pattern: createInline(/!?\[(?:(?!\])<inner>)+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)| ?\[(?:(?!\])<inner>)+\])/.source, false),
176+
lookbehind: true,
177+
greedy: true,
177178
inside: {
178179
'variable': {
179-
pattern: /(!?\[)[^\]]+(?=\]$)/,
180+
pattern: /(\[)[^\]]+(?=\]$)/,
180181
lookbehind: true
181182
},
183+
'content': {
184+
pattern: /(^!?\[)[^\]]+(?=\])/,
185+
lookbehind: true,
186+
inside: {} // see below
187+
},
182188
'string': {
183189
pattern: /"(?:\\.|[^"\\])*"(?=\)$)/
184190
}
185191
}
186192
}
187193
});
188194

189-
['bold', 'italic', 'strike'].forEach(function (token) {
195+
['url', 'bold', 'italic', 'strike'].forEach(function (token) {
190196
['url', 'bold', 'italic', 'strike'].forEach(function (inside) {
191197
if (token !== inside) {
192198
Prism.languages.markdown[token].inside.content.inside[inside] = Prism.languages.markdown[inside];

components/prism-markdown.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

known-failures.html

-12
Original file line numberDiff line numberDiff line change
@@ -153,18 +153,6 @@ <h3>Functions with a single string parameter not using parentheses are not highl
153153
</section>
154154

155155

156-
<section class="language-markdown">
157-
158-
<h3>Nesting of elements is not fully supported</h3>
159-
<pre><code>[Link partially *italic* DOESN'T work](http://example.com)
160-
_ [But link inside italic DOES work](http://example.com) _
161-
162-
[Link partially **bold** DOESN'T work](http://example.com)
163-
__ [But link inside bold DOES work](http://example.com) __</code></pre>
164-
165-
</section>
166-
167-
168156
<section class="language-nasm">
169157

170158
<h3>Numbers with underscores</h3>

tests/languages/markdown/bold_feature.test

+10-2
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,11 @@ __foo[bar](baz)__
113113
["content", [
114114
"foo",
115115
["url", [
116-
"[bar](baz)"
116+
"[",
117+
["content", [
118+
"bar"
119+
]],
120+
"](baz)"
117121
]]
118122
]],
119123
["punctuation", "__"]
@@ -183,7 +187,11 @@ __foo[bar](baz)__
183187
["content", [
184188
"foo",
185189
["url", [
186-
"[bar](baz)"
190+
"[",
191+
["content", [
192+
"bar"
193+
]],
194+
"](baz)"
187195
]]
188196
]],
189197
["punctuation", "**"]

tests/languages/markdown/italic_feature.test

+10-2
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,11 @@ _foo[bar](baz)_
113113
["content", [
114114
"foo",
115115
["url", [
116-
"[bar](baz)"
116+
"[",
117+
["content", [
118+
"bar"
119+
]],
120+
"](baz)"
117121
]]
118122
]],
119123
["punctuation", "_"]
@@ -183,7 +187,11 @@ _foo[bar](baz)_
183187
["content", [
184188
"foo",
185189
["url", [
186-
"[bar](baz)"
190+
"[",
191+
["content", [
192+
"bar"
193+
]],
194+
"](baz)"
187195
]]
188196
]],
189197
["punctuation", "*"]

tests/languages/markdown/strike_feature.test

+10-2
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,11 @@ bar~
113113
["content", [
114114
"foo",
115115
["url", [
116-
"[bar](baz)"
116+
"[",
117+
["content", [
118+
"bar"
119+
]],
120+
"](baz)"
117121
]]
118122
]],
119123
["punctuation", "~"]
@@ -183,7 +187,11 @@ bar~
183187
["content", [
184188
"foo",
185189
["url", [
186-
"[bar](baz)"
190+
"[",
191+
["content", [
192+
"bar"
193+
]],
194+
"](baz)"
187195
]]
188196
]],
189197
["punctuation", "~~"]
+133-4
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,154 @@
11
[foo](http://prismjs.com)
22
![foo](http://prismjs.com "Foo\"bar")
3+
[foo][bar]
34
[foo] [bar]
45

6+
[foo
7+
bar](http://prismjs.com)
8+
9+
[foo *bar* baz](http://prismjs.com)
10+
[foo _bar_ baz](http://prismjs.com)
11+
[foo **bar** baz](http://prismjs.com)
12+
[foo __bar__ baz](http://prismjs.com)
13+
[foo ~bar~ baz](http://prismjs.com)
14+
[foo ~~bar~~ baz](http://prismjs.com)
15+
516
----------------------------------------------------
617

718
[
819
["url", [
9-
"[foo](http://prismjs.com)"
20+
"[",
21+
["content", [
22+
"foo"
23+
]],
24+
"](http://prismjs.com)"
1025
]],
1126
["url", [
12-
"![foo](http://prismjs.com ",
27+
"![",
28+
["content", [
29+
"foo"
30+
]],
31+
"](http://prismjs.com ",
1332
["string", "\"Foo\\\"bar\""],
1433
")"
1534
]],
1635
["url", [
17-
"[foo] [",
36+
"[",
37+
["content", [
38+
"foo"
39+
]],
40+
"][",
41+
["variable", "bar"],
42+
"]"
43+
]],
44+
["url", [
45+
"[",
46+
["content", [
47+
"foo"
48+
]],
49+
"] [",
1850
["variable", "bar"],
1951
"]"
52+
]],
53+
["url", [
54+
"[",
55+
["content", [
56+
"foo\r\nbar"
57+
]],
58+
"](http://prismjs.com)"
59+
]],
60+
["url", [
61+
"[",
62+
["content", [
63+
"foo ",
64+
["italic", [
65+
["punctuation", "*"],
66+
["content", [
67+
"bar"
68+
]],
69+
["punctuation", "*"]
70+
]],
71+
" baz"
72+
]],
73+
"](http://prismjs.com)"
74+
]],
75+
["url", [
76+
"[",
77+
["content", [
78+
"foo ",
79+
["italic", [
80+
["punctuation", "_"],
81+
["content", [
82+
"bar"
83+
]],
84+
["punctuation", "_"]
85+
]],
86+
" baz"
87+
]],
88+
"](http://prismjs.com)"
89+
]],
90+
["url", [
91+
"[",
92+
["content", [
93+
"foo ",
94+
["bold", [
95+
["punctuation", "**"],
96+
["content", [
97+
"bar"
98+
]],
99+
["punctuation", "**"]
100+
]],
101+
" baz"
102+
]],
103+
"](http://prismjs.com)"
104+
]],
105+
["url", [
106+
"[",
107+
["content", [
108+
"foo ",
109+
["bold", [
110+
["punctuation", "__"],
111+
["content", [
112+
"bar"
113+
]],
114+
["punctuation", "__"]
115+
]],
116+
" baz"
117+
]],
118+
"](http://prismjs.com)"
119+
]],
120+
["url", [
121+
"[",
122+
["content", [
123+
"foo ",
124+
["strike", [
125+
["punctuation", "~"],
126+
["content", [
127+
"bar"
128+
]],
129+
["punctuation", "~"]
130+
]],
131+
" baz"
132+
]],
133+
"](http://prismjs.com)"
134+
]],
135+
["url", [
136+
"[",
137+
["content", [
138+
"foo ",
139+
["strike", [
140+
["punctuation", "~~"],
141+
["content", [
142+
"bar"
143+
]],
144+
["punctuation", "~~"]
145+
]],
146+
" baz"
147+
]],
148+
"](http://prismjs.com)"
20149
]]
21150
]
22151

23152
----------------------------------------------------
24153

25-
Checks for URLs.
154+
Checks for URLs.

0 commit comments

Comments
 (0)