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/"" 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=""and quotes" '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" '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=""and quotes" '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 "and quotes"" 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"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 '"and quotes"" 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&that">link</a></p>' 127 ) 128 self.assertMarkdownRenders( 129 '[title](http://example.com/?a=1&b=2)', 130 '<p><a href="http://example.com/?a=1&b=2">title</a></p>' 131 ) 132 self.assertMarkdownRenders( 133 '[title](http://example.com/?a=1&b=2)', 134 '<p><a href="http://example.com/?a=1&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>"title"">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"title"">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"">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