• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1"""
2Python Markdown
3
4A Python implementation of John Gruber's Markdown.
5
6Documentation: https://python-markdown.github.io/
7GitHub: https://github.com/Python-Markdown/markdown/
8PyPI: https://pypi.org/project/Markdown/
9
10Started by Manfred Stienstra (http://www.dwerg.net/).
11Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org).
12Currently maintained by Waylan Limberg (https://github.com/waylan),
13Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser).
14
15Copyright 2007-2018 The Python Markdown Project (v. 1.7 and later)
16Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b)
17Copyright 2004 Manfred Stienstra (the original version)
18
19License: BSD (see LICENSE.md for details).
20"""
21
22from markdown.test_tools import TestCase
23
24
25class TestInlineLinks(TestCase):
26
27    def test_nested_square_brackets(self):
28        self.assertMarkdownRenders(
29            """[Text[[[[[[[]]]]]]][]](http://link.com) more text""",
30            """<p><a href="http://link.com">Text[[[[[[[]]]]]]][]</a> more text</p>"""
31        )
32
33    def test_nested_round_brackets(self):
34        self.assertMarkdownRenders(
35            """[Text](http://link.com/(((((((()))))))())) more text""",
36            """<p><a href="http://link.com/(((((((()))))))())">Text</a> more text</p>"""
37        )
38
39    def test_uneven_brackets_with_titles1(self):
40        self.assertMarkdownRenders(
41            """[Text](http://link.com/("title") more text""",
42            """<p><a href="http://link.com/(" title="title">Text</a> more text</p>"""
43        )
44
45    def test_uneven_brackets_with_titles2(self):
46        self.assertMarkdownRenders(
47            """[Text](http://link.com/('"title") more text""",
48            """<p><a href="http://link.com/('" title="title">Text</a> more text</p>"""
49        )
50
51    def test_uneven_brackets_with_titles3(self):
52        self.assertMarkdownRenders(
53            """[Text](http://link.com/("title)") more text""",
54            """<p><a href="http://link.com/(" title="title)">Text</a> more text</p>"""
55        )
56
57    def test_uneven_brackets_with_titles4(self):
58        self.assertMarkdownRenders(
59            """[Text](http://link.com/( "title") more text""",
60            """<p><a href="http://link.com/(" title="title">Text</a> more text</p>"""
61        )
62
63    def test_uneven_brackets_with_titles5(self):
64        self.assertMarkdownRenders(
65            """[Text](http://link.com/( "title)") more text""",
66            """<p><a href="http://link.com/(" title="title)">Text</a> more text</p>"""
67        )
68
69    def test_mixed_title_quotes1(self):
70        self.assertMarkdownRenders(
71            """[Text](http://link.com/'"title") more text""",
72            """<p><a href="http://link.com/'" title="title">Text</a> more text</p>"""
73        )
74
75    def test_mixed_title_quotes2(self):
76        self.assertMarkdownRenders(
77            """[Text](http://link.com/"'title') more text""",
78            """<p><a href="http://link.com/&quot;" title="title">Text</a> more text</p>"""
79        )
80
81    def test_mixed_title_quotes3(self):
82        self.assertMarkdownRenders(
83            """[Text](http://link.com/with spaces'"and quotes" 'and title') more text""",
84            """<p><a href="http://link.com/with spaces" title="&quot;and quotes&quot; 'and title">"""
85            """Text</a> more text</p>"""
86        )
87
88    def test_mixed_title_quotes4(self):
89        self.assertMarkdownRenders(
90            """[Text](http://link.com/with spaces'"and quotes" 'and title") more text""",
91            """<p><a href="http://link.com/with spaces'" title="and quotes&quot; 'and title">Text</a> more text</p>"""
92        )
93
94    def test_mixed_title_quotes5(self):
95        self.assertMarkdownRenders(
96            """[Text](http://link.com/with spaces '"and quotes" 'and title') more text""",
97            """<p><a href="http://link.com/with spaces" title="&quot;and quotes&quot; 'and title">"""
98            """Text</a> more text</p>"""
99        )
100
101    def test_mixed_title_quotes6(self):
102        self.assertMarkdownRenders(
103            """[Text](http://link.com/with spaces "and quotes" 'and title') more text""",
104            """<p><a href="http://link.com/with spaces &quot;and quotes&quot;" title="and title">"""
105            """Text</a> more text</p>"""
106        )
107
108    def test_single_quote(self):
109        self.assertMarkdownRenders(
110            """[test](link"notitle)""",
111            """<p><a href="link&quot;notitle">test</a></p>"""
112        )
113
114    def test_angle_with_mixed_title_quotes(self):
115        self.assertMarkdownRenders(
116            """[Text](<http://link.com/with spaces '"and quotes"> 'and title') more text""",
117            """<p><a href="http://link.com/with spaces '&quot;and quotes&quot;" title="and title">"""
118            """Text</a> more text</p>"""
119        )
120
121    def test_amp_in_url(self):
122        """Test amp in URLs."""
123
124        self.assertMarkdownRenders(
125            '[link](http://www.freewisdom.org/this&that)',
126            '<p><a href="http://www.freewisdom.org/this&amp;that">link</a></p>'
127        )
128        self.assertMarkdownRenders(
129            '[title](http://example.com/?a=1&amp;b=2)',
130            '<p><a href="http://example.com/?a=1&amp;b=2">title</a></p>'
131        )
132        self.assertMarkdownRenders(
133            '[title](http://example.com/?a=1&#x26;b=2)',
134            '<p><a href="http://example.com/?a=1&#x26;b=2">title</a></p>'
135        )
136
137
138class TestReferenceLinks(TestCase):
139
140    def test_ref_link(self):
141        self.assertMarkdownRenders(
142            self.dedent(
143                """
144                [Text]
145
146                [Text]: http://example.com
147                """
148            ),
149            """<p><a href="http://example.com">Text</a></p>"""
150        )
151
152    def test_ref_link_angle_brackets(self):
153        self.assertMarkdownRenders(
154            self.dedent(
155                """
156                [Text]
157
158                [Text]: <http://example.com>
159                """
160            ),
161            """<p><a href="http://example.com">Text</a></p>"""
162        )
163
164    def test_ref_link_no_space(self):
165        self.assertMarkdownRenders(
166            self.dedent(
167                """
168                [Text]
169
170                [Text]:http://example.com
171                """
172            ),
173            """<p><a href="http://example.com">Text</a></p>"""
174        )
175
176    def test_ref_link_angle_brackets_no_space(self):
177        self.assertMarkdownRenders(
178            self.dedent(
179                """
180                [Text]
181
182                [Text]:<http://example.com>
183                """
184            ),
185            """<p><a href="http://example.com">Text</a></p>"""
186        )
187
188    def test_ref_link_angle_brackets_title(self):
189        self.assertMarkdownRenders(
190            self.dedent(
191                """
192                [Text]
193
194                [Text]: <http://example.com> "title"
195                """
196            ),
197            """<p><a href="http://example.com" title="title">Text</a></p>"""
198        )
199
200    def test_ref_link_title(self):
201        self.assertMarkdownRenders(
202            self.dedent(
203                """
204                [Text]
205
206                [Text]: http://example.com "title"
207                """
208            ),
209            """<p><a href="http://example.com" title="title">Text</a></p>"""
210        )
211
212    def test_ref_link_angle_brackets_title_no_space(self):
213        # TODO: Maybe reevaluate this?
214        self.assertMarkdownRenders(
215            self.dedent(
216                """
217                [Text]
218
219                [Text]: <http://example.com>"title"
220                """
221            ),
222            """<p><a href="http://example.com&gt;&quot;title&quot;">Text</a></p>"""
223        )
224
225    def test_ref_link_title_no_space(self):
226        self.assertMarkdownRenders(
227            self.dedent(
228                """
229                [Text]
230
231                [Text]: http://example.com"title"
232                """
233            ),
234            """<p><a href="http://example.com&quot;title&quot;">Text</a></p>"""
235        )
236
237    def test_ref_link_single_quoted_title(self):
238        self.assertMarkdownRenders(
239            self.dedent(
240                """
241                [Text]
242
243                [Text]: http://example.com 'title'
244                """
245            ),
246            """<p><a href="http://example.com" title="title">Text</a></p>"""
247        )
248
249    def test_ref_link_title_nested_quote(self):
250        self.assertMarkdownRenders(
251            self.dedent(
252                """
253                [Text]
254
255                [Text]: http://example.com "title'"
256                """
257            ),
258            """<p><a href="http://example.com" title="title'">Text</a></p>"""
259        )
260
261    def test_ref_link_single_quoted_title_nested_quote(self):
262        self.assertMarkdownRenders(
263            self.dedent(
264                """
265                [Text]
266
267                [Text]: http://example.com 'title"'
268                """
269            ),
270            """<p><a href="http://example.com" title="title&quot;">Text</a></p>"""
271        )
272
273    def test_ref_link_override(self):
274        self.assertMarkdownRenders(
275            self.dedent(
276                """
277                [Text]
278
279                [Text]: http://example.com 'ignore'
280                [Text]: https://example.com 'override'
281                """
282            ),
283            """<p><a href="https://example.com" title="override">Text</a></p>"""
284        )
285
286    def test_ref_link_title_no_blank_lines(self):
287        self.assertMarkdownRenders(
288            self.dedent(
289                """
290                [Text]
291                [Text]: http://example.com "title"
292                [Text]
293                """
294            ),
295            self.dedent(
296                """
297                <p><a href="http://example.com" title="title">Text</a></p>
298                <p><a href="http://example.com" title="title">Text</a></p>
299                """
300            )
301        )
302
303    def test_ref_link_multi_line(self):
304        self.assertMarkdownRenders(
305            self.dedent(
306                """
307                [Text]
308
309                [Text]:
310                    http://example.com
311                    "title"
312                """
313            ),
314            """<p><a href="http://example.com" title="title">Text</a></p>"""
315        )
316
317    def test_reference_newlines(self):
318        """Test reference id whitespace cleanup."""
319
320        self.assertMarkdownRenders(
321            self.dedent(
322                """
323                Two things:
324
325                 - I would like to tell you about the [code of
326                   conduct][] we are using in this project.
327                 - Only one in fact.
328
329                [code of conduct]: https://github.com/Python-Markdown/markdown/blob/master/CODE_OF_CONDUCT.md
330                """
331            ),
332            '<p>Two things:</p>\n<ul>\n<li>I would like to tell you about the '
333            '<a href="https://github.com/Python-Markdown/markdown/blob/master/CODE_OF_CONDUCT.md">code of\n'
334            '   conduct</a> we are using in this project.</li>\n<li>Only one in fact.</li>\n</ul>'
335        )
336
337    def test_reference_across_blocks(self):
338        """Test references across blocks."""
339
340        self.assertMarkdownRenders(
341            self.dedent(
342                """
343                I would like to tell you about the [code of
344
345                conduct][] we are using in this project.
346
347                [code of conduct]: https://github.com/Python-Markdown/markdown/blob/master/CODE_OF_CONDUCT.md
348                """
349            ),
350            '<p>I would like to tell you about the [code of</p>\n'
351            '<p>conduct][] we are using in this project.</p>'
352        )
353
354    def test_ref_link_nested_left_bracket(self):
355        self.assertMarkdownRenders(
356            self.dedent(
357                """
358                [Text[]
359
360                [Text[]: http://example.com
361                """
362            ),
363            self.dedent(
364                """
365                <p>[Text[]</p>
366                <p>[Text[]: http://example.com</p>
367                """
368            )
369        )
370
371    def test_ref_link_nested_right_bracket(self):
372        self.assertMarkdownRenders(
373            self.dedent(
374                """
375                [Text]]
376
377                [Text]]: http://example.com
378                """
379            ),
380            self.dedent(
381                """
382                <p>[Text]]</p>
383                <p>[Text]]: http://example.com</p>
384                """
385            )
386        )
387