From d18c3d0acab0e7469c3284c897afcb61f9dd1fea Mon Sep 17 00:00:00 2001 From: Isaac Muse Date: Wed, 17 Jan 2018 18:36:34 -0700 Subject: Flexible inline (#629) Add new InlineProcessor class that handles inline processing much better and allows for more flexibility. This adds new InlineProcessors that no longer utilize unnecessary pretext and posttext captures. New class can accept the buffer that is being worked on and manually process the text without regex and return new replacement bounds. This helps us to handle links in a better way and handle nested brackets and logic that is too much for regular expression. The refactor also allows image links to have links/paths with spaces like links. Ref #551, #613, #590, #161. --- tests/misc/image.html | 5 -- tests/misc/image.txt | 12 --- tests/test_apis.py | 10 +-- tests/test_syntax/inline/__init__.py | 0 tests/test_syntax/inline/images.py | 139 +++++++++++++++++++++++++++++++++++ tests/test_syntax/inline/links.py | 98 ++++++++++++++++++++++++ 6 files changed, 242 insertions(+), 22 deletions(-) delete mode 100644 tests/misc/image.html delete mode 100644 tests/misc/image.txt create mode 100644 tests/test_syntax/inline/__init__.py create mode 100644 tests/test_syntax/inline/images.py create mode 100644 tests/test_syntax/inline/links.py (limited to 'tests') diff --git a/tests/misc/image.html b/tests/misc/image.html deleted file mode 100644 index 1171e4e..0000000 --- a/tests/misc/image.html +++ /dev/null @@ -1,5 +0,0 @@ -

Poster

-

Poster

-

Blank

-

![Fail](http://humane man.jpg "The most humane man.")

-

![Fail](http://humane man.jpg)

\ No newline at end of file diff --git a/tests/misc/image.txt b/tests/misc/image.txt deleted file mode 100644 index 3fae16a..0000000 --- a/tests/misc/image.txt +++ /dev/null @@ -1,12 +0,0 @@ - -![Poster](http://humane_man.jpg "The most humane man.") - -![Poster][] - -[Poster]:http://humane_man.jpg "The most humane man." - -![Blank]() - -![Fail](http://humane man.jpg "The most humane man.") - -![Fail](http://humane man.jpg) diff --git a/tests/test_apis.py b/tests/test_apis.py index aa43e52..15ecc5b 100644 --- a/tests/test_apis.py +++ b/tests/test_apis.py @@ -753,16 +753,16 @@ class TestEscapeAppend(unittest.TestCase): class TestAncestorExclusion(unittest.TestCase): """ Tests exclusion of tags in ancestor list. """ - class AncestorExample(markdown.inlinepatterns.SimpleTagPattern): + class AncestorExample(markdown.inlinepatterns.SimpleTagInlineProcessor): """ Ancestor Test. """ ANCESTOR_EXCLUDES = ('a',) - def handleMatch(self, m): + def handleMatch(self, m, data): """ Handle match. """ el = markdown.util.etree.Element(self.tag) - el.text = m.group(3) - return el + el.text = m.group(2) + return el, m.start(0), m.end(0) class AncestorExtension(markdown.Extension): @@ -774,7 +774,7 @@ class TestAncestorExclusion(unittest.TestCase): def extendMarkdown(self, md, md_globals): """Modify inline patterns.""" - pattern = r'(\+)([^\+]+)\2' + pattern = r'(\+)([^\+]+)\1' md.inlinePatterns["ancestor-test"] = TestAncestorExclusion.AncestorExample(pattern, 'strong') def setUp(self): diff --git a/tests/test_syntax/inline/__init__.py b/tests/test_syntax/inline/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_syntax/inline/images.py b/tests/test_syntax/inline/images.py new file mode 100644 index 0000000..9c1dc34 --- /dev/null +++ b/tests/test_syntax/inline/images.py @@ -0,0 +1,139 @@ +from markdown.test_tools import TestCase + + +class TestAdvancedImages(TestCase): + + def test_nested_square_brackets(self): + self.assertMarkdownRenders( + """![Text[[[[[[[]]]]]]][]](http://link.com/image.png) more text""", + """

Text[[[[[[[]]]]]]][] more text

""" + ) + + def test_nested_round_brackets(self): + self.assertMarkdownRenders( + """![Text](http://link.com/(((((((()))))))()).png) more text""", + """

Text more text

""" + ) + + def test_uneven_brackets_with_titles1(self): + self.assertMarkdownRenders( + """![Text](http://link.com/(.png"title") more text""", + """

Text more text

""" + ) + + def test_uneven_brackets_with_titles2(self): + self.assertMarkdownRenders( + """![Text](http://link.com/('.png"title") more text""", + """

Text more text

""" + ) + + def test_uneven_brackets_with_titles3(self): + self.assertMarkdownRenders( + """![Text](http://link.com/(.png"title)") more text""", + """

Text more text

""" + ) + + def test_uneven_brackets_with_titles4(self): + self.assertMarkdownRenders( + """![Text](http://link.com/(.png "title") more text""", + """

Text more text

""" + ) + + def test_uneven_brackets_with_titles5(self): + self.assertMarkdownRenders( + """![Text](http://link.com/(.png "title)") more text""", + """

Text more text

""" + ) + + def test_mixed_title_quotes1(self): + self.assertMarkdownRenders( + """![Text](http://link.com/'.png"title") more text""", + """

Text more text

""" + ) + + def test_mixed_title_quotes2(self): + self.assertMarkdownRenders( + """![Text](http://link.com/".png'title') more text""", + """

Text more text

""" + ) + + def test_mixed_title_quotes3(self): + self.assertMarkdownRenders( + """![Text](http://link.com/with spaces.png'"and quotes" 'and title') more text""", + """

Text""" + """ more text

""" + ) + + def test_mixed_title_quotes4(self): + self.assertMarkdownRenders( + """![Text](http://link.com/with spaces'.png"and quotes" 'and title") more text""", + """

Text""" + """ more text

""" + ) + + def test_mixed_title_quotes5(self): + self.assertMarkdownRenders( + """![Text](http://link.com/with spaces .png'"and quotes" 'and title') more text""", + """

Text more text

""" + ) + + def test_mixed_title_quotes6(self): + self.assertMarkdownRenders( + """![Text](http://link.com/with spaces "and quotes".png 'and title') more text""", + """

Text""" + """ more text

""" + ) + + def test_single_quote(self): + self.assertMarkdownRenders( + """![test](link"notitle.png)""", + """

test

""" + ) + + def test_angle_with_mixed_title_quotes(self): + self.assertMarkdownRenders( + """![Text]( 'and title') more text""", + """

Text""" + """ more text

""" + ) + + def test_misc(self): + self.assertMarkdownRenders( + """![Poster](http://humane_man.jpg "The most humane man.")""", + """

Poster

""" + ) + + def test_misc_ref(self): + self.assertMarkdownRenders( + self.dedent( + """ + ![Poster][] + + [Poster]:http://humane_man.jpg "The most humane man." + """ + ), + self.dedent( + """ +

Poster

+ """ + ) + ) + + def test_misc_blank(self): + self.assertMarkdownRenders( + """![Blank]()""", + """

Blank

""" + ) + + def test_misc_img_title(self): + self.assertMarkdownRenders( + """![Image](http://humane man.jpg "The most humane man.")""", + """

Image

""" + ) + + def test_misc_img(self): + self.assertMarkdownRenders( + """![Image](http://humane man.jpg)""", + """

Image

""" + ) diff --git a/tests/test_syntax/inline/links.py b/tests/test_syntax/inline/links.py new file mode 100644 index 0000000..fe58ada --- /dev/null +++ b/tests/test_syntax/inline/links.py @@ -0,0 +1,98 @@ +from markdown.test_tools import TestCase + + +class TestAdvancedLinks(TestCase): + + def test_nested_square_brackets(self): + self.assertMarkdownRenders( + """[Text[[[[[[[]]]]]]][]](http://link.com) more text""", + """

Text[[[[[[[]]]]]]][] more text

""" + ) + + def test_nested_round_brackets(self): + self.assertMarkdownRenders( + """[Text](http://link.com/(((((((()))))))())) more text""", + """

Text more text

""" + ) + + def test_uneven_brackets_with_titles1(self): + self.assertMarkdownRenders( + """[Text](http://link.com/("title") more text""", + """

Text more text

""" + ) + + def test_uneven_brackets_with_titles2(self): + self.assertMarkdownRenders( + """[Text](http://link.com/('"title") more text""", + """

Text more text

""" + ) + + def test_uneven_brackets_with_titles3(self): + self.assertMarkdownRenders( + """[Text](http://link.com/("title)") more text""", + """

Text more text

""" + ) + + def test_uneven_brackets_with_titles4(self): + self.assertMarkdownRenders( + """[Text](http://link.com/( "title") more text""", + """

Text more text

""" + ) + + def test_uneven_brackets_with_titles5(self): + self.assertMarkdownRenders( + """[Text](http://link.com/( "title)") more text""", + """

Text more text

""" + ) + + def test_mixed_title_quotes1(self): + self.assertMarkdownRenders( + """[Text](http://link.com/'"title") more text""", + """

Text more text

""" + ) + + def test_mixed_title_quotes2(self): + self.assertMarkdownRenders( + """[Text](http://link.com/"'title') more text""", + """

Text more text

""" + ) + + def test_mixed_title_quotes3(self): + self.assertMarkdownRenders( + """[Text](http://link.com/with spaces'"and quotes" 'and title') more text""", + """

""" + """Text more text

""" + ) + + def test_mixed_title_quotes4(self): + self.assertMarkdownRenders( + """[Text](http://link.com/with spaces'"and quotes" 'and title") more text""", + """

Text more text

""" + ) + + def test_mixed_title_quotes5(self): + self.assertMarkdownRenders( + """[Text](http://link.com/with spaces '"and quotes" 'and title') more text""", + """

""" + """Text more text

""" + ) + + def test_mixed_title_quotes6(self): + self.assertMarkdownRenders( + """[Text](http://link.com/with spaces "and quotes" 'and title') more text""", + """

""" + """Text more text

""" + ) + + def test_single_quote(self): + self.assertMarkdownRenders( + """[test](link"notitle)""", + """

test

""" + ) + + def test_angle_with_mixed_title_quotes(self): + self.assertMarkdownRenders( + """[Text]( 'and title') more text""", + """

""" + """Text more text

""" + ) -- cgit v1.2.3