From b6def457d78db8a9d056251239b4cbfd8c5cfda7 Mon Sep 17 00:00:00 2001 From: ryanvilbrandt Date: Thu, 21 Nov 2019 09:46:16 -0800 Subject: [PATCH 001/477] Ignore .idea directory --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 722351f9..f02ff09f 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ sandbox/*.html __pycache__ .tox *.egg-info +*.idea From b750e6c207cb62119f547d632a12da1ac470a02e Mon Sep 17 00:00:00 2001 From: ryanvilbrandt Date: Thu, 21 Nov 2019 11:02:52 -0800 Subject: [PATCH 002/477] Added headers to wiki table Also indentation --- lib/markdown2.py | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/lib/markdown2.py b/lib/markdown2.py index 49bedd06..cfb3ee87 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -217,6 +217,7 @@ def __init__(self, html4tags=False, tab_width=4, safe_mode=None, else: self.empty_element_suffix = " />" self.tab_width = tab_width + self.tab = tab_width * " " # For compatibility with earlier markdown2.py and with # markdown.py's safe_mode being a boolean, @@ -1070,23 +1071,36 @@ def _do_tables(self, text): def _wiki_table_sub(self, match): ttext = match.group(0).strip() - # print 'wiki table: %r' % match.group(0) + # print('wiki table: %r' % match.group(0)) rows = [] for line in ttext.splitlines(0): line = line.strip()[2:-2].strip() row = [c.strip() for c in re.split(r'(?' % self._html_class_str_from_tag('table'), ''] + hlines = [] + def add_hline(line, indents=0): + hlines.append((self.tab * indents) + line) + add_hline('' % self._html_class_str_from_tag('table')) + create_thead = rows and rows[0] and re.match(r"\s*~", rows[0][0]) + add_hline('<{}>'.format("thead" if create_thead else "tbody"), 1) for row in rows: - hrow = [''] + add_hline('', 2) for cell in row: - hrow.append('') - hrow.append(self._run_span_gamut(cell)) - hrow.append('') - hrow.append('') - hlines.append(''.join(hrow)) - hlines += ['', ''] + cell_type = "td" + cell = cell.strip(" ") + if cell.strip(" ").startswith("~"): + cell = cell[1:].strip(" ") + cell_type = "th" + add_hline('<{0}>{1}'.format(cell_type, self._run_span_gamut(cell)), 3) + add_hline('', 2) + if create_thead: + add_hline('', 1) + add_hline('', 1) + create_thead = False + add_hline('', 1) + add_hline('') return '\n'.join(hlines) + '\n' def _do_wiki_tables(self, text): From f2d187ba1757eb08ff60dc80ad86fc23d53f0dd0 Mon Sep 17 00:00:00 2001 From: ryanvilbrandt Date: Thu, 21 Nov 2019 11:03:28 -0800 Subject: [PATCH 003/477] Added header row test --- test/tm-cases/wiki_tables.html | 90 ++++++++++++++++++++++++++++------ test/tm-cases/wiki_tables.tags | 2 +- test/tm-cases/wiki_tables.text | 5 ++ 3 files changed, 80 insertions(+), 17 deletions(-) diff --git a/test/tm-cases/wiki_tables.html b/test/tm-cases/wiki_tables.html index 45d7cc35..f61f109e 100644 --- a/test/tm-cases/wiki_tables.html +++ b/test/tm-cases/wiki_tables.html @@ -1,28 +1,83 @@ - - - - - - + + + + + + + + + + + + + + + + + + + + + + +
YearTemperature (low)Temperature (high)
1900-1025
1910-1530
1920-1032
YearTemperature (low)Temperature (high)
1900-1025
1910-1530
1920-1032
+ +

With header row

+ + + + + + + + + + + + + + + + + + + + + + + +
NameClassRaceLevel
VladBarbarianDragonborn12
JimboRogueHalfling13

just one line

- - - + + + + + + +
foobarbaz
foobarbaz

blockquote

- - - - + + + + + + + + + + + +
grinchstolexmas
greeneggsham
grinchstolexmas
greeneggsham

-- Dr. Seuss

@@ -31,7 +86,10 @@

blockquote

end of file

- - - + + + + + +
ResourceNotFoundIf :login does not exist
ResourceNotFoundIf :login does not exist
diff --git a/test/tm-cases/wiki_tables.tags b/test/tm-cases/wiki_tables.tags index b333de63..362500d5 100644 --- a/test/tm-cases/wiki_tables.tags +++ b/test/tm-cases/wiki_tables.tags @@ -1 +1 @@ -extra wiki-tables issue66 +extra wiki-tables diff --git a/test/tm-cases/wiki_tables.text b/test/tm-cases/wiki_tables.text index a707804b..ce11b203 100644 --- a/test/tm-cases/wiki_tables.text +++ b/test/tm-cases/wiki_tables.text @@ -3,6 +3,11 @@ || 1910 || -15 || 30 || || 1920 || -10 || 32 || +# With header row + +||~ Name ||~ Class ||~ Race ||~ Level || +|| Vlad || Barbarian || Dragonborn || 12 || +|| Jimbo || Rogue || Halfling || 13 || # just one line From 0a4b5065d175fb9958c197d8104cbc7b1141d64d Mon Sep 17 00:00:00 2001 From: ryanvilbrandt Date: Thu, 21 Nov 2019 11:07:14 -0800 Subject: [PATCH 004/477] Alternate spacing test --- test/tm-cases/wiki_tables.html | 27 +++++++++++++++++++++++++++ test/tm-cases/wiki_tables.text | 6 ++++++ 2 files changed, 33 insertions(+) diff --git a/test/tm-cases/wiki_tables.html b/test/tm-cases/wiki_tables.html index f61f109e..cd04d795 100644 --- a/test/tm-cases/wiki_tables.html +++ b/test/tm-cases/wiki_tables.html @@ -50,6 +50,33 @@

With header row

+

With header row, alternate spacing

+ + + + + + + + + + + + + + + + + + + + + + + + +
NameClassRaceLevel
VladBarbarianDragonborn12
JimboRogueHalfling13
+

just one line

diff --git a/test/tm-cases/wiki_tables.text b/test/tm-cases/wiki_tables.text index ce11b203..e60c5c13 100644 --- a/test/tm-cases/wiki_tables.text +++ b/test/tm-cases/wiki_tables.text @@ -9,6 +9,12 @@ || Vlad || Barbarian || Dragonborn || 12 || || Jimbo || Rogue || Halfling || 13 || +# With header row, alternate spacing + +|| ~Name || ~Class || ~Race || ~Level || +|| Vlad || Barbarian || Dragonborn || 12 || +|| Jimbo || Rogue || Halfling || 13 || + # just one line ||foo||bar||baz|| From 7fc8f480017feac2b98ba5c6ea18f3115011e6d4 Mon Sep 17 00:00:00 2001 From: ryanvilbrandt Date: Thu, 21 Nov 2019 16:10:25 -0800 Subject: [PATCH 005/477] Added "tables" extra and added leading pipe to empty cells Empty cells must be completely surrounded by pipes --- test/php-markdown-extra-cases/Tables.html | 2 +- test/php-markdown-extra-cases/Tables.opts | 1 + test/php-markdown-extra-cases/Tables.text | 9 ++++----- 3 files changed, 6 insertions(+), 6 deletions(-) create mode 100644 test/php-markdown-extra-cases/Tables.opts diff --git a/test/php-markdown-extra-cases/Tables.html b/test/php-markdown-extra-cases/Tables.html index e36286c8..408693ec 100644 --- a/test/php-markdown-extra-cases/Tables.html +++ b/test/php-markdown-extra-cases/Tables.html @@ -307,4 +307,4 @@

Missing tailing pipe

-
Cell
\ No newline at end of file + diff --git a/test/php-markdown-extra-cases/Tables.opts b/test/php-markdown-extra-cases/Tables.opts new file mode 100644 index 00000000..23983798 --- /dev/null +++ b/test/php-markdown-extra-cases/Tables.opts @@ -0,0 +1 @@ +{"extras": ["tables"]} diff --git a/test/php-markdown-extra-cases/Tables.text b/test/php-markdown-extra-cases/Tables.text index 71b93ca6..3deb3a69 100644 --- a/test/php-markdown-extra-cases/Tables.text +++ b/test/php-markdown-extra-cases/Tables.text @@ -73,10 +73,10 @@ Table alignement (alternate spacing): | A | B | | C | | -Header 1 | Header 2 ---------- | --------- -A | B - | D +| Header 1 | Header 2 +| --------- | --------- +| A | B +| | D * * * @@ -101,4 +101,3 @@ Header 1 | Header 2 | --------- | --------- | Cell | Cell | Cell | Cell - From ebd8be8e0c9e6eb5ddec52912f917741da4ad90a Mon Sep 17 00:00:00 2001 From: ryanvilbrandt Date: Thu, 21 Nov 2019 16:15:20 -0800 Subject: [PATCH 006/477] Indent and add proper headers to more wiki tables --- test/tm-cases/html_classes.html | 30 ++++++++++++++++++++++++------ test/tm-cases/html_classes.text | 2 +- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/test/tm-cases/html_classes.html b/test/tm-cases/html_classes.html index e5d4bc00..f40aeda0 100644 --- a/test/tm-cases/html_classes.html +++ b/test/tm-cases/html_classes.html @@ -18,12 +18,30 @@ - - - - - - + + + + + + + + + + + + + + + + + + + + + + + +
YearTemperature (low)Temperature (high)
1900-1025
1910-1530
1920-1032
YearTemperature (low)Temperature (high)
1900-1025
1910-1530
1920-1032

For example:

diff --git a/test/tm-cases/html_classes.text b/test/tm-cases/html_classes.text index 61972c80..190b037d 100644 --- a/test/tm-cases/html_classes.text +++ b/test/tm-cases/html_classes.text @@ -3,7 +3,7 @@ | `Cell 1` | [Cell 2](http://example.com) link | | Cell 3 | **Cell 4** | -|| *Year* || *Temperature (low)* || *Temperature (high)* || +||~ Year ||~ Temperature (low) ||~ Temperature (high) || || 1900 || -10 || 25 || || 1910 || -15 || 30 || || 1920 || -10 || 32 || From 4f5efc0b98aea66aa5c5a63ecb9a54acf0d0f906 Mon Sep 17 00:00:00 2001 From: ryanvilbrandt Date: Thu, 21 Nov 2019 17:03:04 -0800 Subject: [PATCH 007/477] Removed extraneous strip() --- lib/markdown2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/markdown2.py b/lib/markdown2.py index cfb3ee87..e7f4bd08 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -1090,7 +1090,7 @@ def add_hline(line, indents=0): for cell in row: cell_type = "td" cell = cell.strip(" ") - if cell.strip(" ").startswith("~"): + if cell.startswith("~"): cell = cell[1:].strip(" ") cell_type = "th" add_hline('<{0}>{1}'.format(cell_type, self._run_span_gamut(cell)), 3) From c9ba74779ea11b18b5883e9d1e0f1d3d170be5db Mon Sep 17 00:00:00 2001 From: ryanvilbrandt Date: Thu, 21 Nov 2019 22:31:36 -0800 Subject: [PATCH 008/477] Cleaned up wiki table logic --- lib/markdown2.py | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/lib/markdown2.py b/lib/markdown2.py index e7f4bd08..766e1e1a 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -1080,26 +1080,33 @@ def _wiki_table_sub(self, match): # from pprint import pprint # pprint(rows) hlines = [] + def add_hline(line, indents=0): hlines.append((self.tab * indents) + line) + + def format_cell(text): + return self._run_span_gamut(re.sub(r"^\s*~", "", cell).strip(" ")) + add_hline('' % self._html_class_str_from_tag('table')) - create_thead = rows and rows[0] and re.match(r"\s*~", rows[0][0]) - add_hline('<{}>'.format("thead" if create_thead else "tbody"), 1) - for row in rows: + # Check if first cell of first row is a header cell. If so, assume the whole row is a header row. + if rows and rows[0] and re.match(r"^\s*~", rows[0][0]): + add_hline('', 1) add_hline('', 2) - for cell in row: - cell_type = "td" - cell = cell.strip(" ") - if cell.startswith("~"): - cell = cell[1:].strip(" ") - cell_type = "th" - add_hline('<{0}>{1}'.format(cell_type, self._run_span_gamut(cell)), 3) + for cell in rows[0]: + add_hline("{}".format(format_cell(cell)), 3) add_hline('', 2) - if create_thead: - add_hline('', 1) - add_hline('', 1) - create_thead = False - add_hline('', 1) + add_hline('', 1) + # Only one header row allowed. + rows = rows[1:] + # If no more rows, don't create a tbody. + if rows: + add_hline('', 1) + for row in rows: + add_hline('', 2) + for cell in row: + add_hline('{}'.format(format_cell(cell)), 3) + add_hline('', 2) + add_hline('', 1) add_hline('') return '\n'.join(hlines) + '\n' From 7f91f7683268024f509b15aec37515ed8b52ee04 Mon Sep 17 00:00:00 2001 From: ryanvilbrandt Date: Thu, 21 Nov 2019 22:31:52 -0800 Subject: [PATCH 009/477] Header-only test --- test/tm-cases/wiki_tables.html | 13 +++++++++++++ test/tm-cases/wiki_tables.text | 4 ++++ 2 files changed, 17 insertions(+) diff --git a/test/tm-cases/wiki_tables.html b/test/tm-cases/wiki_tables.html index cd04d795..64bc1b52 100644 --- a/test/tm-cases/wiki_tables.html +++ b/test/tm-cases/wiki_tables.html @@ -50,6 +50,19 @@

With header row

+

With only header row

+ + + + + + + + + + +
NameClassRaceLevel
+

With header row, alternate spacing

diff --git a/test/tm-cases/wiki_tables.text b/test/tm-cases/wiki_tables.text index e60c5c13..1128d4bf 100644 --- a/test/tm-cases/wiki_tables.text +++ b/test/tm-cases/wiki_tables.text @@ -9,6 +9,10 @@ || Vlad || Barbarian || Dragonborn || 12 || || Jimbo || Rogue || Halfling || 13 || +# With only header row + +||~ Name ||~ Class ||~ Race ||~ Level || + # With header row, alternate spacing || ~Name || ~Class || ~Race || ~Level || From 5628b51174044d9e27b675a67e4e9f4d98ba7fbf Mon Sep 17 00:00:00 2001 From: ryanvilbrandt Date: Fri, 22 Nov 2019 17:57:20 -0800 Subject: [PATCH 010/477] Reset _toc every time markdown conversion happens --- lib/markdown2.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/markdown2.py b/lib/markdown2.py index 49bedd06..ac3041e9 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -202,6 +202,8 @@ class Markdown(object): html_spans = None html_removed_text = "[HTML_REMOVED]" # for compat with markdown.py + _toc = None + # Used to track when we're inside an ordered or unordered list # (see _ProcessListItems() for details): list_level = 0 @@ -273,6 +275,7 @@ def reset(self): self._count_from_header_id = defaultdict(int) if "metadata" in self.extras: self.metadata = {} + self._toc = None # Per "rel" # should only be used in tags with an "href" attribute. @@ -1509,7 +1512,6 @@ def header_id_from_text(self, text, prefix, n): return header_id - _toc = None def _toc_add_entry(self, level, id, name): if level > self._toc_depth: return From 37c0d77542c8ecef1ffa8ad47fe6fca18c3e3aa9 Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Sun, 24 Nov 2019 21:18:40 -0500 Subject: [PATCH 011/477] Changes and contributors --- CHANGES.md | 2 +- CONTRIBUTORS.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 9b27c624..315c5059 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,7 +2,7 @@ ## python-markdown2 2.3.9 (not yet released) -(nothing yet) +- [pull #335] Added header support for wiki tables ## python-markdown2 2.3.8 diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index be989934..bd8deb15 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -42,3 +42,4 @@ Sym Roe (github.com/symroe) Alex Elzenaar (github.com/aelzenaar) Francisco Saldaña (github.com/FrankSalad) Shivam Kumar Jha (github.com/thealphadollar) +ryanvilbrandt (github.com/ryanvilbrandt) From b7946ebeca3296450e9c540bbd72b0bfd58923d9 Mon Sep 17 00:00:00 2001 From: ryanvilbrandt Date: Mon, 25 Nov 2019 08:23:18 -0800 Subject: [PATCH 012/477] Added unit test for toc_html fix --- test/test_markdown2.py | 45 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/test/test_markdown2.py b/test/test_markdown2.py index d0b3133f..0d2199e4 100644 --- a/test/test_markdown2.py +++ b/test/test_markdown2.py @@ -291,6 +291,51 @@ def test_russian(self): '

%s

\n' % ko) test_russian.tags = ["unicode", "issue3"] + def test_toc_with_persistent_object(self): + """ + Tests that the toc is the same every time it's run on HTML, even if the Markdown object isn't disposed of. + """ + md = markdown2.Markdown(extras=["toc"]) + html = """ +# Header 1 +## Header 1.1 +## Header 1.2 +### Header 1.3 +# Header 2 +## Header 2.1 + """ + expected_toc_html = """
+""" + self.assertEqual(expected_toc_html, md.convert(html).toc_html) + # Do it again, to check if the toc_html is just appended rather than replaced + self.assertEqual(expected_toc_html, md.convert(html).toc_html) + # Create different html, and confirm toc_html is replaced + html = """ +# I'm new html +## I don't have to be long, just different +""" + expected_toc_html = """ +""" + self.assertEqual(expected_toc_html, md.convert(html).toc_html) + class DocTestsTestCase(unittest.TestCase): def test_api(self): From 83f8068837c07c527cbe49f98acfdfca1e8aa329 Mon Sep 17 00:00:00 2001 From: ryanvilbrandt Date: Mon, 25 Nov 2019 08:27:34 -0800 Subject: [PATCH 013/477] Added unit test tags property. Not sure if necessary. --- test/test_markdown2.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/test_markdown2.py b/test/test_markdown2.py index 0d2199e4..010de139 100644 --- a/test/test_markdown2.py +++ b/test/test_markdown2.py @@ -335,6 +335,7 @@ def test_toc_with_persistent_object(self): """ self.assertEqual(expected_toc_html, md.convert(html).toc_html) + test_toc_with_persistent_object.tags = ["toc", "issue208"] class DocTestsTestCase(unittest.TestCase): From c89cd966b6e4b38a418b941e85a07c5e66a3b5fb Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Mon, 25 Nov 2019 13:10:14 -0500 Subject: [PATCH 014/477] Changes --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 315c5059..d0083af6 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,7 @@ ## python-markdown2 2.3.9 (not yet released) - [pull #335] Added header support for wiki tables +- [pull #336] Reset _toc when convert is run ## python-markdown2 2.3.8 From 47801bc62e3b4882c6e3a14f29d69d76d695443a Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Wed, 22 Jan 2020 18:48:18 -0500 Subject: [PATCH 015/477] Ignore venv --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f02ff09f..0b671943 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ __pycache__ .tox *.egg-info *.idea +venv \ No newline at end of file From 55ba78e29ac983978806970ce4b81718fe68275b Mon Sep 17 00:00:00 2001 From: ryanvilbrandt Date: Tue, 26 Nov 2019 13:54:27 -0800 Subject: [PATCH 016/477] Fixed code highlighting unit tests Which broke for some reason?? --- test/tm-cases/fenced_code_blocks_leading_lang_space.html | 4 ++-- test/tm-cases/fenced_code_blocks_safe_highlight.html | 4 ++-- test/tm-cases/fenced_code_blocks_syntax_highlighting.html | 4 ++-- test/tm-cases/fenced_code_blocks_syntax_indentation.html | 4 ++-- test/tm-cases/issue3_bad_code_color_hack.html | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/test/tm-cases/fenced_code_blocks_leading_lang_space.html b/test/tm-cases/fenced_code_blocks_leading_lang_space.html index 8f7a090a..a61524b3 100644 --- a/test/tm-cases/fenced_code_blocks_leading_lang_space.html +++ b/test/tm-cases/fenced_code_blocks_leading_lang_space.html @@ -1,3 +1,3 @@ -
if True:
-    print "hi"
+
if True:
+    print "hi"
 
diff --git a/test/tm-cases/fenced_code_blocks_safe_highlight.html b/test/tm-cases/fenced_code_blocks_safe_highlight.html index df5bbec5..a08985a7 100644 --- a/test/tm-cases/fenced_code_blocks_safe_highlight.html +++ b/test/tm-cases/fenced_code_blocks_safe_highlight.html @@ -1,5 +1,5 @@ -
if True:
-    print "hi"
+
if True:
+    print "hi"
 

That's using the fenced-code-blocks extra with Python diff --git a/test/tm-cases/fenced_code_blocks_syntax_highlighting.html b/test/tm-cases/fenced_code_blocks_syntax_highlighting.html index df5bbec5..a08985a7 100644 --- a/test/tm-cases/fenced_code_blocks_syntax_highlighting.html +++ b/test/tm-cases/fenced_code_blocks_syntax_highlighting.html @@ -1,5 +1,5 @@ -

if True:
-    print "hi"
+
if True:
+    print "hi"
 

That's using the fenced-code-blocks extra with Python diff --git a/test/tm-cases/fenced_code_blocks_syntax_indentation.html b/test/tm-cases/fenced_code_blocks_syntax_indentation.html index 11a7c241..37b5723e 100644 --- a/test/tm-cases/fenced_code_blocks_syntax_indentation.html +++ b/test/tm-cases/fenced_code_blocks_syntax_indentation.html @@ -1,5 +1,5 @@

def foo():
-    print "foo"
+    print "foo"
 
-    print "bar"
+    print "bar"
 
diff --git a/test/tm-cases/issue3_bad_code_color_hack.html b/test/tm-cases/issue3_bad_code_color_hack.html index 46f329aa..8aedb76c 100644 --- a/test/tm-cases/issue3_bad_code_color_hack.html +++ b/test/tm-cases/issue3_bad_code_color_hack.html @@ -7,6 +7,6 @@

заголовок

Some python code:

# комментарий
-if True:
-    print "hi"
+if True:
+    print "hi"
 
From 4d2fc792abd7fbf8ddec937812857f13fded61cf Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Wed, 22 Jan 2020 18:56:18 -0500 Subject: [PATCH 017/477] Remove 3.4, add 3.8 --- .travis.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 93208f8f..543f2ffb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,11 @@ language: python python: - - "2.7" - "pypy" - - "3.4" - "3.5" - "3.6" - - "3.7-dev" + - "3.7" + - "3.8" # command to install dependencies -install: pip install Pygments>=2.1.1 +install: pip install Pygments>=2.5.2 # command to run tests script: make testone From 5db3e6e92a51ad8a98c73411962ecbe96c9a737e Mon Sep 17 00:00:00 2001 From: Gareth Simpson Date: Fri, 1 May 2020 14:21:08 +0100 Subject: [PATCH 018/477] Issue 341 - XSS in link text --- lib/markdown2.py | 10 +++++++++- test/tm-cases/issue341_xss.html | 5 +++++ test/tm-cases/issue341_xss.opts | 1 + test/tm-cases/issue341_xss.text | 5 +++++ 4 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 test/tm-cases/issue341_xss.html create mode 100644 test/tm-cases/issue341_xss.opts create mode 100644 test/tm-cases/issue341_xss.text diff --git a/lib/markdown2.py b/lib/markdown2.py index 3a5d5d9b..38b7bea8 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -200,7 +200,8 @@ class Markdown(object): titles = None html_blocks = None html_spans = None - html_removed_text = "[HTML_REMOVED]" # for compat with markdown.py + html_removed_text = "{(#HTML#)}" # placeholder removed text that does not trigger bold + html_removed_text_compat = "[HTML_REMOVED]" # for compat with markdown.py _toc = None @@ -388,6 +389,8 @@ def convert(self, text): if self.safe_mode: text = self._unhash_html_spans(text) + # return the removed text warning to its markdown.py compatible form + text = text.replace(self.html_removed_text, self.html_removed_text_compat) if "nofollow" in self.extras: text = self._a_nofollow.sub(r'<\1 rel="nofollow"\2', text) @@ -1375,6 +1378,11 @@ def _do_links(self, text): continue link_text = text[start_idx+1:p] + # Fix for issue 341 - Injecting XSS into link text + if self.safe_mode: + link_text = self._hash_html_spans(link_text) + link_text = self._unhash_html_spans(link_text) + # Possibly a footnote ref? if "footnotes" in self.extras and link_text.startswith("^"): normed_id = re.sub(r'\W', '-', link_text[1:]) diff --git a/test/tm-cases/issue341_xss.html b/test/tm-cases/issue341_xss.html new file mode 100644 index 00000000..48aedff9 --- /dev/null +++ b/test/tm-cases/issue341_xss.html @@ -0,0 +1,5 @@ +

Example 1: +[HTML_REMOVED]alert(1);//>[HTML_REMOVED]>

+ +

Example 2: +[HTML_REMOVED]alert(1);/*->a>a\\*/[HTML_REMOVED]alert(1);/*->a>

diff --git a/test/tm-cases/issue341_xss.opts b/test/tm-cases/issue341_xss.opts new file mode 100644 index 00000000..fd31b4e3 --- /dev/null +++ b/test/tm-cases/issue341_xss.opts @@ -0,0 +1 @@ +{"safe_mode": "replace"} diff --git a/test/tm-cases/issue341_xss.text b/test/tm-cases/issue341_xss.text new file mode 100644 index 00000000..8707ce23 --- /dev/null +++ b/test/tm-cases/issue341_xss.text @@ -0,0 +1,5 @@ +Example 1: +alert(1);//]()>]()> + +Example 2: +alert(1);/\*](http://g)->a>alert(1);/*](http://g)->a> \ No newline at end of file From 9144d0fc5d5249cc4d81287ee79091806e6dde52 Mon Sep 17 00:00:00 2001 From: Gareth Simpson Date: Fri, 1 May 2020 19:31:21 +0100 Subject: [PATCH 019/477] Fix for issue 348 - incomplete tags with punctuation after as part of the tag name are a source of XSS --- lib/markdown2.py | 2 +- test/tm-cases/issue348_incomplete_tag.html | 1 + test/tm-cases/issue348_incomplete_tag.opts | 1 + test/tm-cases/issue348_incomplete_tag.text | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 test/tm-cases/issue348_incomplete_tag.html create mode 100644 test/tm-cases/issue348_incomplete_tag.opts create mode 100644 test/tm-cases/issue348_incomplete_tag.text diff --git a/lib/markdown2.py b/lib/markdown2.py index 3a5d5d9b..636bf075 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -2164,7 +2164,7 @@ def _encode_amps_and_angles(self, text): text = self._naked_gt_re.sub('>', text) return text - _incomplete_tags_re = re.compile("<(/?\w+[\s/]+?)") + _incomplete_tags_re = re.compile("<(/?\w+?(?!://).?[\s/]+?)") def _encode_incomplete_tags(self, text): if self.safe_mode not in ("replace", "escape"): diff --git a/test/tm-cases/issue348_incomplete_tag.html b/test/tm-cases/issue348_incomplete_tag.html new file mode 100644 index 00000000..46059cc6 --- /dev/null +++ b/test/tm-cases/issue348_incomplete_tag.html @@ -0,0 +1 @@ +

<lol@/ //id="pwn"//onclick="alert(1)"//abc

diff --git a/test/tm-cases/issue348_incomplete_tag.opts b/test/tm-cases/issue348_incomplete_tag.opts new file mode 100644 index 00000000..ad487c04 --- /dev/null +++ b/test/tm-cases/issue348_incomplete_tag.opts @@ -0,0 +1 @@ +{"safe_mode": "escape"} diff --git a/test/tm-cases/issue348_incomplete_tag.text b/test/tm-cases/issue348_incomplete_tag.text new file mode 100644 index 00000000..bb4a0de6 --- /dev/null +++ b/test/tm-cases/issue348_incomplete_tag.text @@ -0,0 +1 @@ + Date: Sat, 2 May 2020 21:22:36 +0100 Subject: [PATCH 020/477] Better fix for issue 348 --- lib/markdown2.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/markdown2.py b/lib/markdown2.py index 636bf075..be86502f 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -2164,11 +2164,14 @@ def _encode_amps_and_angles(self, text): text = self._naked_gt_re.sub('>', text) return text - _incomplete_tags_re = re.compile("<(/?\w+?(?!://).?[\s/]+?)") + _incomplete_tags_re = re.compile("<(/?\w+?(?!\w).+?[\s/]+?)") def _encode_incomplete_tags(self, text): if self.safe_mode not in ("replace", "escape"): return text + + if text.endswith(">"): + return text # this is not an incomplete tag, this is a link in the form return self._incomplete_tags_re.sub("<\\1", text) From 06fe2dfb4da814efc938579c98838c45564e8ec3 Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Mon, 4 May 2020 13:00:43 -0400 Subject: [PATCH 021/477] Changes and contributors --- CHANGES.md | 1 + CONTRIBUTORS.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index d0083af6..f2953b40 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,6 +4,7 @@ - [pull #335] Added header support for wiki tables - [pull #336] Reset _toc when convert is run +- [pull #353] XSS fix ## python-markdown2 2.3.8 diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index bd8deb15..5b47a3bc 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -43,3 +43,4 @@ Alex Elzenaar (github.com/aelzenaar) Francisco Saldaña (github.com/FrankSalad) Shivam Kumar Jha (github.com/thealphadollar) ryanvilbrandt (github.com/ryanvilbrandt) +Gareth Simpson (github.com/xurble) From 5b5bfe9660b1fb3ac02578e21997805a78bfe1f8 Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Mon, 11 May 2020 17:24:48 -0400 Subject: [PATCH 022/477] Changes --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index f2953b40..770c41d9 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,6 +5,7 @@ - [pull #335] Added header support for wiki tables - [pull #336] Reset _toc when convert is run - [pull #353] XSS fix +- [pull #350] XSS fix ## python-markdown2 2.3.8 From 9bd56944b0db00edec8fce5849ea48dba9e15759 Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Mon, 11 May 2020 20:07:44 -0400 Subject: [PATCH 023/477] prepare for 2.3.9 release --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 770c41d9..cc4bdd84 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,6 @@ # python-markdown2 Changelog -## python-markdown2 2.3.9 (not yet released) +## python-markdown2 2.3.9 - [pull #335] Added header support for wiki tables - [pull #336] Reset _toc when convert is run From 8c0ddb3f7002b2aa5aa8cdcb981d6d75e9ae05da Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Mon, 11 May 2020 20:08:02 -0400 Subject: [PATCH 024/477] prep for future dev --- CHANGES.md | 5 +++++ lib/markdown2.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index cc4bdd84..9e23b548 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,10 @@ # python-markdown2 Changelog +## python-markdown2 2.3.10 (not yet released) + +(nothing yet) + + ## python-markdown2 2.3.9 - [pull #335] Added header support for wiki tables diff --git a/lib/markdown2.py b/lib/markdown2.py index 5048413c..4b55d11b 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -96,7 +96,7 @@ # not yet sure if there implications with this. Compare 'pydoc sre' # and 'perldoc perlre'. -__version_info__ = (2, 3, 9) +__version_info__ = (2, 3, 10) __version__ = '.'.join(map(str, __version_info__)) __author__ = "Trent Mick" From ef8844fd03661eb65db2ce9fd0a224adc1319e5d Mon Sep 17 00:00:00 2001 From: Kat Hagan Date: Thu, 11 Jun 2020 19:00:29 -0700 Subject: [PATCH 025/477] don't match whitespace between blockquotes --- lib/markdown2.py | 1 - test/tm-cases/blockquote_two_in_a_row.html | 7 +++++++ test/tm-cases/blockquote_two_in_a_row.text | 3 +++ 3 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 test/tm-cases/blockquote_two_in_a_row.html create mode 100644 test/tm-cases/blockquote_two_in_a_row.text diff --git a/lib/markdown2.py b/lib/markdown2.py index 4b55d11b..fbec3e29 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -2027,7 +2027,6 @@ def _do_smart_punctuation(self, text): ^[ \t]*>%s[ \t]? # '>' at the start of a line .+\n # rest of the first line (.+\n)* # subsequent consecutive lines - \n* # blanks )+ ) ''' diff --git a/test/tm-cases/blockquote_two_in_a_row.html b/test/tm-cases/blockquote_two_in_a_row.html new file mode 100644 index 00000000..5d3be31b --- /dev/null +++ b/test/tm-cases/blockquote_two_in_a_row.html @@ -0,0 +1,7 @@ +
+

no way

+
+ +
+

way

+
diff --git a/test/tm-cases/blockquote_two_in_a_row.text b/test/tm-cases/blockquote_two_in_a_row.text new file mode 100644 index 00000000..4ecb87e5 --- /dev/null +++ b/test/tm-cases/blockquote_two_in_a_row.text @@ -0,0 +1,3 @@ +> no way + +> way From 7d3c6d6a3f0a03b1231f7559ebefb7a6a52f8908 Mon Sep 17 00:00:00 2001 From: Kat Hagan Date: Thu, 11 Jun 2020 19:10:06 -0700 Subject: [PATCH 026/477] add a test for blockquotes containing newlines --- test/tm-cases/blockquote_containing_empty_lines.html | 5 +++++ test/tm-cases/blockquote_containing_empty_lines.text | 4 ++++ 2 files changed, 9 insertions(+) create mode 100644 test/tm-cases/blockquote_containing_empty_lines.html create mode 100644 test/tm-cases/blockquote_containing_empty_lines.text diff --git a/test/tm-cases/blockquote_containing_empty_lines.html b/test/tm-cases/blockquote_containing_empty_lines.html new file mode 100644 index 00000000..e572602c --- /dev/null +++ b/test/tm-cases/blockquote_containing_empty_lines.html @@ -0,0 +1,5 @@ +
+

no way

+ +

way

+
diff --git a/test/tm-cases/blockquote_containing_empty_lines.text b/test/tm-cases/blockquote_containing_empty_lines.text new file mode 100644 index 00000000..ea9460eb --- /dev/null +++ b/test/tm-cases/blockquote_containing_empty_lines.text @@ -0,0 +1,4 @@ +> no way +> +> +> way From e440084f092f0a689642f558c42ad2a75047236d Mon Sep 17 00:00:00 2001 From: Kat Hagan Date: Sat, 13 Jun 2020 17:18:30 -0700 Subject: [PATCH 027/477] change to text-align for table alignment and update tests --- lib/markdown2.py | 6 ++-- test/php-markdown-extra-cases/Tables.html | 40 +++++++++++------------ test/php-markdown-extra-cases/Tables.text | 12 +++---- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/lib/markdown2.py b/lib/markdown2.py index 4b55d11b..eb066151 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -1013,11 +1013,11 @@ def _table_sub(self, match): align_from_col_idx = {} for col_idx, col in enumerate(cols): if col[0] == ':' and col[-1] == ':': - align_from_col_idx[col_idx] = ' align="center"' + align_from_col_idx[col_idx] = ' style="text-align:center;"' elif col[0] == ':': - align_from_col_idx[col_idx] = ' align="left"' + align_from_col_idx[col_idx] = ' style="text-align:left;"' elif col[-1] == ':': - align_from_col_idx[col_idx] = ' align="right"' + align_from_col_idx[col_idx] = ' style="text-align:right;"' # thead hlines = ['' % self._html_class_str_from_tag('table'), '
', ''] diff --git a/test/php-markdown-extra-cases/Tables.html b/test/php-markdown-extra-cases/Tables.html index 408693ec..95b9c2a9 100644 --- a/test/php-markdown-extra-cases/Tables.html +++ b/test/php-markdown-extra-cases/Tables.html @@ -133,56 +133,56 @@

One-column one-row table


-

Table alignement:

+

Table alignment:

- - - + + + - - - + + + - - - + + +
DefaultRightCenterLeftLeftCenterRight
Long CellLong CellLong CellLong CellLong CellLong CellLong Cell
CellCellCellCellCellCellCell
-

Table alignement (alternate spacing):

+

Table alignment (alternate spacing):

- - - + + + - - - + + + - - - + + +
DefaultRightCenterLeftLeftCenterRight
Long CellLong CellLong CellLong CellLong CellLong CellLong Cell
CellCellCellCellCellCellCell
diff --git a/test/php-markdown-extra-cases/Tables.text b/test/php-markdown-extra-cases/Tables.text index 3deb3a69..b761ad91 100644 --- a/test/php-markdown-extra-cases/Tables.text +++ b/test/php-markdown-extra-cases/Tables.text @@ -50,19 +50,19 @@ With leading and tailing pipes: * * * -Table alignement: +Table alignment: -| Default | Right | Center | Left | +| Default | Left | Center | Right | | --------- |:--------- |:---------:| ---------:| | Long Cell | Long Cell | Long Cell | Long Cell | -| Cell | Cell | Cell | Cell | +| Cell | Cell | Cell | Cell | -Table alignement (alternate spacing): +Table alignment (alternate spacing): -| Default | Right | Center | Left | +| Default | Left | Center | Right | | --------- | :-------- | :-------: | --------: | | Long Cell | Long Cell | Long Cell | Long Cell | -| Cell | Cell | Cell | Cell | +| Cell | Cell | Cell | Cell | * * * From 4858c40fc1cd6122245049bb4eb906872d32dfff Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Mon, 15 Jun 2020 22:10:44 -0400 Subject: [PATCH 028/477] Changes and contributors --- CHANGES.md | 2 +- CONTRIBUTORS.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 9e23b548..3594fb93 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,7 +2,7 @@ ## python-markdown2 2.3.10 (not yet released) -(nothing yet) +- [pull #356] Don't merge sequential quotes into a single blockquote ## python-markdown2 2.3.9 diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 5b47a3bc..0f324354 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -44,3 +44,4 @@ Francisco Saldaña (github.com/FrankSalad) Shivam Kumar Jha (github.com/thealphadollar) ryanvilbrandt (github.com/ryanvilbrandt) Gareth Simpson (github.com/xurble) +Kat Hagan (github.com/codebykat) From fc557cbff73ba6e84a8317934932a72018653959 Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Mon, 15 Jun 2020 22:31:45 -0400 Subject: [PATCH 029/477] Changes --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 3594fb93..6b5e9729 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,7 @@ ## python-markdown2 2.3.10 (not yet released) - [pull #356] Don't merge sequential quotes into a single blockquote +- [pull #357] use style=text-align for table alignment ## python-markdown2 2.3.9 From 176d116c746b496e560196d2dc2b33b666f93346 Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Mon, 15 Jun 2020 22:38:16 -0400 Subject: [PATCH 030/477] Run php extras tests, mark knownfailure --- test/php-markdown-extra-cases/Abbr.tags | 1 + test/php-markdown-extra-cases/Definition Lists.tags | 1 + test/php-markdown-extra-cases/Emphasis.tags | 1 + test/php-markdown-extra-cases/Footnotes.tags | 1 + .../Inline HTML with Markdown content.tags | 1 + test/test_markdown2.py | 1 - 6 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 test/php-markdown-extra-cases/Abbr.tags create mode 100644 test/php-markdown-extra-cases/Definition Lists.tags create mode 100644 test/php-markdown-extra-cases/Emphasis.tags create mode 100644 test/php-markdown-extra-cases/Footnotes.tags create mode 100644 test/php-markdown-extra-cases/Inline HTML with Markdown content.tags mode change 100644 => 100755 test/test_markdown2.py diff --git a/test/php-markdown-extra-cases/Abbr.tags b/test/php-markdown-extra-cases/Abbr.tags new file mode 100644 index 00000000..0019958f --- /dev/null +++ b/test/php-markdown-extra-cases/Abbr.tags @@ -0,0 +1 @@ +knownfailure diff --git a/test/php-markdown-extra-cases/Definition Lists.tags b/test/php-markdown-extra-cases/Definition Lists.tags new file mode 100644 index 00000000..0019958f --- /dev/null +++ b/test/php-markdown-extra-cases/Definition Lists.tags @@ -0,0 +1 @@ +knownfailure diff --git a/test/php-markdown-extra-cases/Emphasis.tags b/test/php-markdown-extra-cases/Emphasis.tags new file mode 100644 index 00000000..0019958f --- /dev/null +++ b/test/php-markdown-extra-cases/Emphasis.tags @@ -0,0 +1 @@ +knownfailure diff --git a/test/php-markdown-extra-cases/Footnotes.tags b/test/php-markdown-extra-cases/Footnotes.tags new file mode 100644 index 00000000..0019958f --- /dev/null +++ b/test/php-markdown-extra-cases/Footnotes.tags @@ -0,0 +1 @@ +knownfailure diff --git a/test/php-markdown-extra-cases/Inline HTML with Markdown content.tags b/test/php-markdown-extra-cases/Inline HTML with Markdown content.tags new file mode 100644 index 00000000..0019958f --- /dev/null +++ b/test/php-markdown-extra-cases/Inline HTML with Markdown content.tags @@ -0,0 +1 @@ +knownfailure diff --git a/test/test_markdown2.py b/test/test_markdown2.py old mode 100644 new mode 100755 index 010de139..363934f8 --- a/test/test_markdown2.py +++ b/test/test_markdown2.py @@ -230,7 +230,6 @@ class PHPMarkdownExtraTestCase(_MarkdownTestCase): syntax no implemented in markdown2.py. See for details. """ - __tags__ = ["knownfailure"] cases_dir = "php-markdown-extra-cases" From e87b08290898c232587cbecb242e557b13ce17a8 Mon Sep 17 00:00:00 2001 From: starry69 Date: Thu, 18 Jun 2020 01:27:17 +0530 Subject: [PATCH 031/477] Add underline 'ins' support Signed-off-by: starry69 --- lib/markdown2.py | 8 ++++++++ test/tm-cases/ins.html | 3 +++ test/tm-cases/ins.opts | 1 + test/tm-cases/ins.tags | 1 + test/tm-cases/ins.text | 3 +++ 5 files changed, 16 insertions(+) create mode 100644 test/tm-cases/ins.html create mode 100644 test/tm-cases/ins.opts create mode 100644 test/tm-cases/ins.tags create mode 100644 test/tm-cases/ins.text diff --git a/lib/markdown2.py b/lib/markdown2.py index 0cc651ee..94a78d0a 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -1153,6 +1153,9 @@ def _run_span_gamut(self, text): if "strike" in self.extras: text = self._do_strike(text) + if "ins" in self.extras: + text = self._do_underline(text) + text = self._do_italics_and_bold(text) if "smarty-pants" in self.extras: @@ -1954,6 +1957,11 @@ def _do_strike(self, text): text = self._strike_re.sub(r"\1", text) return text + _ins_re = re.compile(r"--(?=\S)(.+?)(?<=\S)--", re.S) + def _do_underline(self, text): + text = self._ins_re.sub(r"\1", text) + return text + _strong_re = re.compile(r"(\*\*|__)(?=\S)(.+?[*_]*)(?<=\S)\1", re.S) _em_re = re.compile(r"(\*|_)(?=\S)(.+?)(?<=\S)\1", re.S) _code_friendly_strong_re = re.compile(r"\*\*(?=\S)(.+?[*_]*)(?<=\S)\*\*", re.S) diff --git a/test/tm-cases/ins.html b/test/tm-cases/ins.html new file mode 100644 index 00000000..bd3bd5a8 --- /dev/null +++ b/test/tm-cases/ins.html @@ -0,0 +1,3 @@ +

This is underline text.

+ +

So is this word.

diff --git a/test/tm-cases/ins.opts b/test/tm-cases/ins.opts new file mode 100644 index 00000000..99b33771 --- /dev/null +++ b/test/tm-cases/ins.opts @@ -0,0 +1 @@ +{"extras": ["ins"]} diff --git a/test/tm-cases/ins.tags b/test/tm-cases/ins.tags new file mode 100644 index 00000000..0243d733 --- /dev/null +++ b/test/tm-cases/ins.tags @@ -0,0 +1 @@ +extras ins diff --git a/test/tm-cases/ins.text b/test/tm-cases/ins.text new file mode 100644 index 00000000..4307ba95 --- /dev/null +++ b/test/tm-cases/ins.text @@ -0,0 +1,3 @@ +--This is underline line-- + +So is --this-- word. From 07b25dbcdded7d56c0fc0f59154f4718a898147d Mon Sep 17 00:00:00 2001 From: starry69 Date: Thu, 18 Jun 2020 04:16:58 +0530 Subject: [PATCH 032/477] Use 'u' instead of 'ins' Signed-off-by: starry69 --- lib/markdown2.py | 4 ++-- test/tm-cases/ins.html | 4 ++-- test/tm-cases/ins.opts | 2 +- test/tm-cases/ins.tags | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/markdown2.py b/lib/markdown2.py index 94a78d0a..a73a4373 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -1153,7 +1153,7 @@ def _run_span_gamut(self, text): if "strike" in self.extras: text = self._do_strike(text) - if "ins" in self.extras: + if "underline" in self.extras: text = self._do_underline(text) text = self._do_italics_and_bold(text) @@ -1959,7 +1959,7 @@ def _do_strike(self, text): _ins_re = re.compile(r"--(?=\S)(.+?)(?<=\S)--", re.S) def _do_underline(self, text): - text = self._ins_re.sub(r"\1", text) + text = self._ins_re.sub(r"\1", text) return text _strong_re = re.compile(r"(\*\*|__)(?=\S)(.+?[*_]*)(?<=\S)\1", re.S) diff --git a/test/tm-cases/ins.html b/test/tm-cases/ins.html index bd3bd5a8..bd8892dc 100644 --- a/test/tm-cases/ins.html +++ b/test/tm-cases/ins.html @@ -1,3 +1,3 @@ -

This is underline text.

+

This is underline text.

-

So is this word.

+

So is this word.

diff --git a/test/tm-cases/ins.opts b/test/tm-cases/ins.opts index 99b33771..5722f05c 100644 --- a/test/tm-cases/ins.opts +++ b/test/tm-cases/ins.opts @@ -1 +1 @@ -{"extras": ["ins"]} +{"extras": ["underline"]} diff --git a/test/tm-cases/ins.tags b/test/tm-cases/ins.tags index 0243d733..c166945c 100644 --- a/test/tm-cases/ins.tags +++ b/test/tm-cases/ins.tags @@ -1 +1 @@ -extras ins +extras underline From a67f47e5b2f114d88efca7f5c671306828215fcb Mon Sep 17 00:00:00 2001 From: starry69 Date: Thu, 25 Jun 2020 11:23:20 +0530 Subject: [PATCH 033/477] Fix tests not passing Signed-off-by: starry69 --- test/tm-cases/ins.html | 4 +--- test/tm-cases/ins.text | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/test/tm-cases/ins.html b/test/tm-cases/ins.html index bd8892dc..ff8f7a47 100644 --- a/test/tm-cases/ins.html +++ b/test/tm-cases/ins.html @@ -1,3 +1 @@ -

This is underline text.

- -

So is this word.

+

This is some underline text.

diff --git a/test/tm-cases/ins.text b/test/tm-cases/ins.text index 4307ba95..8ee0c9f5 100644 --- a/test/tm-cases/ins.text +++ b/test/tm-cases/ins.text @@ -1,3 +1 @@ ---This is underline line-- - -So is --this-- word. +This is some --underline-- text. From 542d6bb61cef6c784de6838cefba9109dfe33bad Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Fri, 26 Jun 2020 13:43:14 -0400 Subject: [PATCH 034/477] Changes and contributors --- CHANGES.md | 1 + CONTRIBUTORS.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 6b5e9729..2cb9fb3a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,6 +4,7 @@ - [pull #356] Don't merge sequential quotes into a single blockquote - [pull #357] use style=text-align for table alignment +- [pull #360] introduce underline extra ## python-markdown2 2.3.9 diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 0f324354..b0a58b5a 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -45,3 +45,4 @@ Shivam Kumar Jha (github.com/thealphadollar) ryanvilbrandt (github.com/ryanvilbrandt) Gareth Simpson (github.com/xurble) Kat Hagan (github.com/codebykat) +Stɑrry Shivɑm (github.com/starry69) From ce854be797d2af7801f54ec552e6df2a018c5155 Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Fri, 26 Jun 2020 13:46:40 -0400 Subject: [PATCH 035/477] Underline cleanup --- lib/markdown2.py | 4 ++-- test/tm-cases/{ins.html => underline.html} | 0 test/tm-cases/{ins.opts => underline.opts} | 0 test/tm-cases/{ins.tags => underline.tags} | 0 test/tm-cases/{ins.text => underline.text} | 0 5 files changed, 2 insertions(+), 2 deletions(-) rename test/tm-cases/{ins.html => underline.html} (100%) rename test/tm-cases/{ins.opts => underline.opts} (100%) rename test/tm-cases/{ins.tags => underline.tags} (100%) rename test/tm-cases/{ins.text => underline.text} (100%) diff --git a/lib/markdown2.py b/lib/markdown2.py index a73a4373..7b81042c 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -1957,9 +1957,9 @@ def _do_strike(self, text): text = self._strike_re.sub(r"\1", text) return text - _ins_re = re.compile(r"--(?=\S)(.+?)(?<=\S)--", re.S) + _underline_re = re.compile(r"--(?=\S)(.+?)(?<=\S)--", re.S) def _do_underline(self, text): - text = self._ins_re.sub(r"\1", text) + text = self._underline_re.sub(r"\1", text) return text _strong_re = re.compile(r"(\*\*|__)(?=\S)(.+?[*_]*)(?<=\S)\1", re.S) diff --git a/test/tm-cases/ins.html b/test/tm-cases/underline.html similarity index 100% rename from test/tm-cases/ins.html rename to test/tm-cases/underline.html diff --git a/test/tm-cases/ins.opts b/test/tm-cases/underline.opts similarity index 100% rename from test/tm-cases/ins.opts rename to test/tm-cases/underline.opts diff --git a/test/tm-cases/ins.tags b/test/tm-cases/underline.tags similarity index 100% rename from test/tm-cases/ins.tags rename to test/tm-cases/underline.tags diff --git a/test/tm-cases/ins.text b/test/tm-cases/underline.text similarity index 100% rename from test/tm-cases/ins.text rename to test/tm-cases/underline.text From e2ba2d865affc9f1f86365890beae85dc8452bf5 Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Fri, 26 Jun 2020 13:49:24 -0400 Subject: [PATCH 036/477] linting --- lib/markdown2.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/markdown2.py b/lib/markdown2.py index 7b81042c..e69a5612 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -108,10 +108,6 @@ from random import random, randint import codecs from collections import defaultdict -try: - from urllib import quote_plus -except ImportError: - from urllib.parse import quote_plus # ---- Python version compat @@ -2384,7 +2380,7 @@ def _regex_from_encoded_pattern(s): if s.startswith('/') and s.rfind('/') != 0: # Parse it: /PATTERN/FLAGS idx = s.rfind('/') - pattern, flags_str = s[1:idx], s[idx+1:] + _, flags_str = s[1:idx], s[idx+1:] flag_from_char = { "i": re.IGNORECASE, "l": re.LOCALE, From d8fdcc2db51560a4dca7ba01ed28db75d705be3b Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Mon, 24 Aug 2020 23:17:25 -0400 Subject: [PATCH 037/477] Fixes #367 --- lib/markdown2.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/markdown2.py b/lib/markdown2.py index e69a5612..e73d8db6 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -40,6 +40,7 @@ Supported extra syntax options (see -x|--extras option below and see for details): +* break-on-newline: Replace single new line characters with
when True * code-friendly: Disable _ and __ for em and strong. * cuddled-lists: Allow lists to be cuddled to the preceding paragraph. * fenced-code-blocks: Allows a code block to not have to be indented From a7da039c081aaeb7c6eb18bba0ab0d76661a2b39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Nasturas?= Date: Fri, 11 Sep 2020 17:49:04 +0200 Subject: [PATCH 038/477] Support for structured and nested values as dictionnaries and list in metadata (#120) --- lib/markdown2.py | 68 +++++++++++++++++++++++++++++---- test/tm-cases/metadata.metadata | 4 +- test/tm-cases/metadata.text | 15 ++++++++ 3 files changed, 79 insertions(+), 8 deletions(-) diff --git a/lib/markdown2.py b/lib/markdown2.py index e73d8db6..8b9a4794 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -440,13 +440,21 @@ def preprocess(self, text): # another-var: blah blah # # # header - _meta_data_pattern = re.compile(r'^(?:---[\ \t]*\n)?(.*:\s+>\n\s+[\S\s]+?)(?=\n\w+\s*:\s*\w+\n|\Z)|([\S\w]+\s*:(?! >)[ \t]*.*\n?)(?:---[\ \t]*\n)?', re.MULTILINE) + _meta_data_pattern = re.compile(r'^(?:---[\ \t]*\n)?((?:[\S\w]+\s*:(?:\n+[ \t]+.*)+)|(?:.*:\s+>\n\s+[\S\s]+?)(?=\n\w+\s*:\s*\w+\n|\Z)|(?:\s*[\S\w]+\s*:(?! >)[ \t]*.*\n?))(?:---[\ \t]*\n)?', re.MULTILINE) _key_val_pat = re.compile(r"[\S\w]+\s*:(?! >)[ \t]*.*\n?", re.MULTILINE) # this allows key: > # value # conutiues over multiple lines _key_val_block_pat = re.compile( - "(.*:\s+>\n\s+[\S\s]+?)(?=\n\w+\s*:\s*\w+\n|\Z)", re.MULTILINE) + r"(.*:\s+>\n\s+[\S\s]+?)(?=\n\w+\s*:\s*\w+\n|\Z)", re.MULTILINE + ) + _key_val_list_pat = re.compile( + r"^-(?:[ \t]*([^:\s]*)(?:[ \t]*[:-][ \t]*(\S+))?)(?:\n((?:[ \t]+[^\n]+\n?)+))?", + re.MULTILINE, + ) + _key_val_dict_pat = re.compile( + r"^([^:\n]+)[ \t]*:[ \t]*([^\n]*)(?:((?:\n[ \t]+[^\n]+)+))?", re.MULTILINE + ) # grp0: key, grp1: value, grp2: multiline value _meta_data_fence_pattern = re.compile(r'^---[\ \t]*\n', re.MULTILINE) _meta_data_newline = re.compile("^\n", re.MULTILINE) @@ -466,13 +474,59 @@ def _extract_metadata(self, text): return text tail = metadata_split[1] - kv = re.findall(self._key_val_pat, metadata_content) - kvm = re.findall(self._key_val_block_pat, metadata_content) - kvm = [item.replace(": >\n", ":", 1) for item in kvm] + def parse_structured_value(value): + print(repr(value)) + vs = value.lstrip() + vs = value.replace(v[: len(value) - len(vs)], "\n")[1:] + + # List + if vs.startswith("-"): + r = [] + for match in re.findall(self._key_val_list_pat, vs): + if match[0] and not match[1] and not match[2]: + r.append(match[0].strip()) + elif match[0] == ">" and not match[1] and match[2]: + r.append(match[2].strip()) + elif match[0] and match[1]: + r.append({match[0].strip(): match[1].strip()}) + elif not match[0] and not match[1] and match[2]: + r.append(parse_structured_value(match[2])) + else: + # Broken case + pass + + return r + + # Dict + else: + return { + match[0].strip(): ( + match[1].strip() + if match[1] + else parse_structured_value(match[2]) + ) + for match in re.findall(self._key_val_dict_pat, vs) + } + + for item in match: - for item in kv + kvm: k, v = item.split(":", 1) - self.metadata[k.strip()] = v.strip() + + # Multiline value + if v[:3] == " >\n": + self.metadata[k.strip()] = v[3:].strip() + + # Empty value + elif v == "\n": + self.metadata[k.strip()] = "" + + # Structured value + elif v[0] == "\n": + self.metadata[k.strip()] = parse_structured_value(v) + + # Simple value + else: + self.metadata[k.strip()] = v.strip() return tail diff --git a/test/tm-cases/metadata.metadata b/test/tm-cases/metadata.metadata index b1eb9146..ebb79271 100644 --- a/test/tm-cases/metadata.metadata +++ b/test/tm-cases/metadata.metadata @@ -5,5 +5,7 @@ "this-is": "a hyphen test", "empty": "", "and some": "long value\n that goes multiline", - "another": "example" + "another": "example", + "alist": ["a", "b", "c"], + "adict": {"key": "foo", "a nested list": ["one", "two", "Even multiline strings are allowed\n in nested structured data\n if linebreaks and indent are respected !", {"subkey": "and another dict in a list"}]} } diff --git a/test/tm-cases/metadata.text b/test/tm-cases/metadata.text index be68e292..b2e14ae8 100644 --- a/test/tm-cases/metadata.text +++ b/test/tm-cases/metadata.text @@ -8,6 +8,21 @@ and some: > long value that goes multiline another: example +alist: + - a + - b + - c +adict: + key: foo + a nested list: + - one + - two + - > + Even multiline strings are allowed + in nested structured data + if linebreaks and indent are respected ! + - + subkey: and another dict in a list --- # The real text From 1ea190ac1c0aad6daf078d17a9b424e452cae71c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Nasturas?= Date: Wed, 16 Sep 2020 11:24:46 +0200 Subject: [PATCH 039/477] Removed useless print --- lib/markdown2.py | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/markdown2.py b/lib/markdown2.py index 8b9a4794..58c1b707 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -475,7 +475,6 @@ def _extract_metadata(self, text): tail = metadata_split[1] def parse_structured_value(value): - print(repr(value)) vs = value.lstrip() vs = value.replace(v[: len(value) - len(vs)], "\n")[1:] From 3abfc5f5fd8099e337bfefd4d12923d04de414ef Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Thu, 17 Sep 2020 20:07:46 -0400 Subject: [PATCH 040/477] Fix for Pygments version bump in tests --- test/tm-cases/syntax_color_opts.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/tm-cases/syntax_color_opts.html b/test/tm-cases/syntax_color_opts.html index 5c928c2d..13d69956 100644 --- a/test/tm-cases/syntax_color_opts.html +++ b/test/tm-cases/syntax_color_opts.html @@ -1,6 +1,6 @@

Here is some sample code:

-
import sys
+
import sys
 def main(argv=sys.argv):
     logging.basicConfig()
     log.info('hi')
@@ -8,7 +8,7 @@
 
 

and:

-
use 'zlib'
+
use 'zlib'
 sub main(argv)
     puts 'hi'
 end

From b9c3b698212ee1edcb189b1e9160e525e5edcefe Mon Sep 17 00:00:00 2001
From: Nicholas Serra 
Date: Thu, 17 Sep 2020 20:13:07 -0400
Subject: [PATCH 041/477] Test pypy3 not pypy

---
 .travis.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.travis.yml b/.travis.yml
index 543f2ffb..55828e0a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,6 +1,6 @@
 language: python
 python:
-  - "pypy"
+  - "pypy3"
   - "3.5"
   - "3.6"
   - "3.7"

From 175fe99880e86d00cc9e2afbb8e6ba11b9d96e1a Mon Sep 17 00:00:00 2001
From: Nicholas Serra 
Date: Thu, 17 Sep 2020 20:16:16 -0400
Subject: [PATCH 042/477] Changes and contributors

---
 CHANGES.md       | 1 +
 CONTRIBUTORS.txt | 1 +
 2 files changed, 2 insertions(+)

diff --git a/CHANGES.md b/CHANGES.md
index 2cb9fb3a..66adddd3 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -5,6 +5,7 @@
 - [pull #356] Don't merge sequential quotes into a single blockquote
 - [pull #357] use style=text-align for table alignment
 - [pull #360] introduce underline extra
+- [pull #368] Support for structured and nested values in metadata
 
 
 ## python-markdown2 2.3.9
diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt
index b0a58b5a..e318051e 100644
--- a/CONTRIBUTORS.txt
+++ b/CONTRIBUTORS.txt
@@ -46,3 +46,4 @@ ryanvilbrandt (github.com/ryanvilbrandt)
 Gareth Simpson (github.com/xurble)
 Kat Hagan (github.com/codebykat)
 Stɑrry Shivɑm (github.com/starry69)
+André Nasturas (github.com/andrenasturas)

From fd81de5d59d6ffcdc73ff9f8541d2262d1e15bc1 Mon Sep 17 00:00:00 2001
From: Alan Hamlett 
Date: Thu, 17 Sep 2020 08:08:03 -0700
Subject: [PATCH 043/477] add noopener to external links

---
 lib/markdown2.py | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/lib/markdown2.py b/lib/markdown2.py
index 58c1b707..b023fae5 100755
--- a/lib/markdown2.py
+++ b/lib/markdown2.py
@@ -389,12 +389,17 @@ def convert(self, text):
             # return the removed text warning to its markdown.py compatible form
             text = text.replace(self.html_removed_text, self.html_removed_text_compat)
 
-        if "nofollow" in self.extras:
-            text = self._a_nofollow.sub(r'<\1 rel="nofollow"\2', text)
-
         if "target-blank-links" in self.extras:
             text = self._a_blank.sub(r'<\1 target="_blank"\2', text)
 
+        if "nofollow" in self.extras:
+            if "target-blank-links" in self.extras:
+                text = self._a_nofollow.sub(r'<\1 rel="nofollow noopener"\2', text)
+            else:
+                text = self._a_nofollow.sub(r'<\1 rel="nofollow"\2', text)
+        elif "target-blank-links" in self.extras:
+            text = self._a_nofollow.sub(r'<\1 rel="noopener"\2', text)
+
         if "toc" in self.extras and self._toc:
             self._toc_html = calculate_toc_html(self._toc)
 
@@ -2234,7 +2239,7 @@ def _encode_amps_and_angles(self, text):
     def _encode_incomplete_tags(self, text):
         if self.safe_mode not in ("replace", "escape"):
             return text
-            
+
         if text.endswith(">"):
             return text  # this is not an incomplete tag, this is a link in the form 
 

From 40050e71df2740e42e079855163c08bde196e266 Mon Sep 17 00:00:00 2001
From: Alan Hamlett 
Date: Thu, 17 Sep 2020 08:22:14 -0700
Subject: [PATCH 044/477] fix tests

---
 test/tm-cases/link_with_blank.html | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/test/tm-cases/link_with_blank.html b/test/tm-cases/link_with_blank.html
index 0d6e1dfe..df2c0037 100644
--- a/test/tm-cases/link_with_blank.html
+++ b/test/tm-cases/link_with_blank.html
@@ -1,5 +1,5 @@
-

Ref

+

Ref

Foo

-

One

+

One

From 7e809a5266e50cf0d18a3ed3ad47da35a6dc9012 Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Fri, 2 Oct 2020 20:37:23 -0400 Subject: [PATCH 045/477] Cleanup conditional and add another test --- lib/markdown2.py | 28 ++++++++++----------- test/tm-cases/link_with_blank_nofollow.html | 5 ++++ test/tm-cases/link_with_blank_nofollow.opts | 1 + test/tm-cases/link_with_blank_nofollow.tags | 1 + test/tm-cases/link_with_blank_nofollow.text | 5 ++++ 5 files changed, 25 insertions(+), 15 deletions(-) create mode 100644 test/tm-cases/link_with_blank_nofollow.html create mode 100644 test/tm-cases/link_with_blank_nofollow.opts create mode 100644 test/tm-cases/link_with_blank_nofollow.tags create mode 100644 test/tm-cases/link_with_blank_nofollow.text diff --git a/lib/markdown2.py b/lib/markdown2.py index b023fae5..d149d0ff 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -278,7 +278,11 @@ def reset(self): # Per "rel" # should only be used in tags with an "href" attribute. - _a_nofollow = re.compile(r""" + + # Opens the linked document in a new window or tab + # should only used in tags with an "href" attribute. + # same with _a_nofollow + _a_nofollow_or_blank_links = re.compile(r""" <(a) ( [^>]* @@ -290,11 +294,6 @@ def reset(self): re.IGNORECASE | re.VERBOSE ) - # Opens the linked document in a new window or tab - # should only used in tags with an "href" attribute. - # same with _a_nofollow - _a_blank = _a_nofollow - def convert(self, text): """Convert the given text.""" # Main function. The order in which other subs are called here is @@ -389,16 +388,15 @@ def convert(self, text): # return the removed text warning to its markdown.py compatible form text = text.replace(self.html_removed_text, self.html_removed_text_compat) - if "target-blank-links" in self.extras: - text = self._a_blank.sub(r'<\1 target="_blank"\2', text) + do_target_blank_links = "target-blank-links" in self.extras + do_nofollow_links = "nofollow" in self.extras - if "nofollow" in self.extras: - if "target-blank-links" in self.extras: - text = self._a_nofollow.sub(r'<\1 rel="nofollow noopener"\2', text) - else: - text = self._a_nofollow.sub(r'<\1 rel="nofollow"\2', text) - elif "target-blank-links" in self.extras: - text = self._a_nofollow.sub(r'<\1 rel="noopener"\2', text) + if do_target_blank_links and do_nofollow_links: + text = self._a_nofollow_or_blank_links.sub(r'<\1 rel="nofollow noopener" target="_blank"\2', text) + elif do_target_blank_links: + text = self._a_nofollow_or_blank_links.sub(r'<\1 rel="noopener" target="_blank"\2', text) + elif do_nofollow_links: + text = self._a_nofollow_or_blank_links.sub(r'<\1 rel="nofollow"\2', text) if "toc" in self.extras and self._toc: self._toc_html = calculate_toc_html(self._toc) diff --git a/test/tm-cases/link_with_blank_nofollow.html b/test/tm-cases/link_with_blank_nofollow.html new file mode 100644 index 00000000..a982dfd0 --- /dev/null +++ b/test/tm-cases/link_with_blank_nofollow.html @@ -0,0 +1,5 @@ +

Ref

+ +

Foo

+ +

One

diff --git a/test/tm-cases/link_with_blank_nofollow.opts b/test/tm-cases/link_with_blank_nofollow.opts new file mode 100644 index 00000000..f1d661fd --- /dev/null +++ b/test/tm-cases/link_with_blank_nofollow.opts @@ -0,0 +1 @@ +{"extras": ["target-blank-links", "nofollow"]} diff --git a/test/tm-cases/link_with_blank_nofollow.tags b/test/tm-cases/link_with_blank_nofollow.tags new file mode 100644 index 00000000..b72d7a3b --- /dev/null +++ b/test/tm-cases/link_with_blank_nofollow.tags @@ -0,0 +1 @@ +extras nofollow blank diff --git a/test/tm-cases/link_with_blank_nofollow.text b/test/tm-cases/link_with_blank_nofollow.text new file mode 100644 index 00000000..1acd167c --- /dev/null +++ b/test/tm-cases/link_with_blank_nofollow.text @@ -0,0 +1,5 @@ +[Ref](http://www.example.com) + +[Foo](#bar) + +[One](http://www.example.com/two#three) From 76c1c1fe02bb17485a98fe347d928397f420ac91 Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Fri, 2 Oct 2020 20:40:24 -0400 Subject: [PATCH 046/477] Changes --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 66adddd3..486565bc 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,7 @@ - [pull #357] use style=text-align for table alignment - [pull #360] introduce underline extra - [pull #368] Support for structured and nested values in metadata +- [pull #371] add noopener to external links ## python-markdown2 2.3.9 From 8b367378811f6073e7a2b26e014912e7097b3fca Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Thu, 15 Oct 2020 20:58:00 +0300 Subject: [PATCH 047/477] Add support for Python 3.8-3.9 --- .travis.yml | 1 + setup.py | 2 ++ 2 files changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 55828e0a..09dc06c0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,7 @@ python: - "3.6" - "3.7" - "3.8" + - "3.9-dev" # command to install dependencies install: pip install Pygments>=2.5.2 # command to run tests diff --git a/setup.py b/setup.py index 1d374829..abdc7e41 100644 --- a/setup.py +++ b/setup.py @@ -26,6 +26,8 @@ Programming Language :: Python :: 3.5 Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 +Programming Language :: Python :: 3.8 +Programming Language :: Python :: 3.9 Operating System :: OS Independent Topic :: Software Development :: Libraries :: Python Modules Topic :: Software Development :: Documentation From 661c9f181524ea19333438870105df7e71be17d5 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Thu, 15 Oct 2020 20:59:33 +0300 Subject: [PATCH 048/477] Cache pip on CI --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 09dc06c0..52d13a84 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,5 @@ language: python +cache: pip python: - "pypy3" - "3.5" From 9812e474d2781a5b70f1d9cbc8dfcf2b7bd39585 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Thu, 15 Oct 2020 21:03:58 +0300 Subject: [PATCH 049/477] Add python_requires to help pip --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index abdc7e41..74d23bfb 100644 --- a/setup.py +++ b/setup.py @@ -51,6 +51,7 @@ package_dir={"": "lib"}, scripts=[script], description="A fast and complete Python implementation of Markdown", + python_requires=">=2.6, !=3.0.*, !=3.1.*, !=3.2.*", classifiers=filter(None, classifiers.split("\n")), long_description="""markdown2: A fast and complete Python implementation of Markdown. From 23163262bc67f0ac21ed3998f66f2c91a1fee349 Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade Date: Thu, 15 Oct 2020 21:05:40 +0300 Subject: [PATCH 050/477] Fix Warning: 'classifiers' should be a list, got type 'filter' --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 74d23bfb..d4bafcb4 100644 --- a/setup.py +++ b/setup.py @@ -52,7 +52,7 @@ scripts=[script], description="A fast and complete Python implementation of Markdown", python_requires=">=2.6, !=3.0.*, !=3.1.*, !=3.2.*", - classifiers=filter(None, classifiers.split("\n")), + classifiers=classifiers.strip().split("\n"), long_description="""markdown2: A fast and complete Python implementation of Markdown. Markdown is a text-to-HTML filter; it translates an easy-to-read / From c5e313c87c4dd5c5633d6c09bd7f4613102598a8 Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Mon, 19 Oct 2020 13:55:01 -0400 Subject: [PATCH 051/477] prepare for 2.3.10 release --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 486565bc..a8b8f5e7 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,6 @@ # python-markdown2 Changelog -## python-markdown2 2.3.10 (not yet released) +## python-markdown2 2.3.10 - [pull #356] Don't merge sequential quotes into a single blockquote - [pull #357] use style=text-align for table alignment From 3aed8ea3612cc035af21fecc620b31c0b1bc5f86 Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Mon, 19 Oct 2020 13:55:15 -0400 Subject: [PATCH 052/477] prep for future dev --- CHANGES.md | 5 +++++ lib/markdown2.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index a8b8f5e7..b3c7ea87 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,10 @@ # python-markdown2 Changelog +## python-markdown2 2.3.11 (not yet released) + +(nothing yet) + + ## python-markdown2 2.3.10 - [pull #356] Don't merge sequential quotes into a single blockquote diff --git a/lib/markdown2.py b/lib/markdown2.py index d149d0ff..307fce19 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -97,7 +97,7 @@ # not yet sure if there implications with this. Compare 'pydoc sre' # and 'perldoc perlre'. -__version_info__ = (2, 3, 10) +__version_info__ = (2, 3, 11) __version__ = '.'.join(map(str, __version_info__)) __author__ = "Trent Mick" From a7f9f24a46290e0ec9abcba06b3817ad0399cef1 Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Mon, 19 Oct 2020 14:03:07 -0400 Subject: [PATCH 053/477] Go to 2.4.0 instead --- CHANGES.md | 2 +- lib/markdown2.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index b3c7ea87..af657f00 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,6 @@ # python-markdown2 Changelog -## python-markdown2 2.3.11 (not yet released) +## python-markdown2 2.4.0 (not yet released) (nothing yet) diff --git a/lib/markdown2.py b/lib/markdown2.py index 307fce19..a79af09f 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -97,7 +97,7 @@ # not yet sure if there implications with this. Compare 'pydoc sre' # and 'perldoc perlre'. -__version_info__ = (2, 3, 11) +__version_info__ = (2, 4, 0) __version__ = '.'.join(map(str, __version_info__)) __author__ = "Trent Mick" From 91d485466ec230d66b898b2774c0acec7916c09f Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Mon, 19 Oct 2020 16:21:22 -0400 Subject: [PATCH 054/477] Update setup.py restrict to Python 3.5 and less than 4 --- setup.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) mode change 100644 => 100755 setup.py diff --git a/setup.py b/setup.py old mode 100644 new mode 100755 index d4bafcb4..822defd5 --- a/setup.py +++ b/setup.py @@ -17,12 +17,7 @@ Intended Audience :: Developers License :: OSI Approved :: MIT License Programming Language :: Python -Programming Language :: Python :: 2 -Programming Language :: Python :: 2.6 -Programming Language :: Python :: 2.7 Programming Language :: Python :: 3 -Programming Language :: Python :: 3.3 -Programming Language :: Python :: 3.4 Programming Language :: Python :: 3.5 Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 @@ -51,7 +46,7 @@ package_dir={"": "lib"}, scripts=[script], description="A fast and complete Python implementation of Markdown", - python_requires=">=2.6, !=3.0.*, !=3.1.*, !=3.2.*", + python_requires=">=3.5, <4", classifiers=classifiers.strip().split("\n"), long_description="""markdown2: A fast and complete Python implementation of Markdown. From 01d1c9d9d20513e7533af7bddc20cb4930d3afe1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Nasturas?= Date: Fri, 27 Nov 2020 15:49:43 +0100 Subject: [PATCH 055/477] Fixed bug breaking strings elements in metadata lists --- lib/markdown2.py | 2 +- test/tm-cases/metadata.metadata | 2 +- test/tm-cases/metadata.text | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/markdown2.py b/lib/markdown2.py index a79af09f..56dd2f11 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -452,7 +452,7 @@ def preprocess(self, text): r"(.*:\s+>\n\s+[\S\s]+?)(?=\n\w+\s*:\s*\w+\n|\Z)", re.MULTILINE ) _key_val_list_pat = re.compile( - r"^-(?:[ \t]*([^:\s]*)(?:[ \t]*[:-][ \t]*(\S+))?)(?:\n((?:[ \t]+[^\n]+\n?)+))?", + r"^-(?:[ \t]*([^\n]*)(?:[ \t]*[:-][ \t]*(\S+))?)(?:\n((?:[ \t]+[^\n]+\n?)+))?", re.MULTILINE, ) _key_val_dict_pat = re.compile( diff --git a/test/tm-cases/metadata.metadata b/test/tm-cases/metadata.metadata index ebb79271..1ee2c4fe 100644 --- a/test/tm-cases/metadata.metadata +++ b/test/tm-cases/metadata.metadata @@ -7,5 +7,5 @@ "and some": "long value\n that goes multiline", "another": "example", "alist": ["a", "b", "c"], - "adict": {"key": "foo", "a nested list": ["one", "two", "Even multiline strings are allowed\n in nested structured data\n if linebreaks and indent are respected !", {"subkey": "and another dict in a list"}]} + "adict": {"key": "foo", "a nested list": ["one", "two", "Even multiline strings are allowed\n in nested structured data\n if linebreaks and indent are respected !", {"subkey": "and another dict in a list"}, "but one-liners remains: simple strings"]} } diff --git a/test/tm-cases/metadata.text b/test/tm-cases/metadata.text index b2e14ae8..c12494df 100644 --- a/test/tm-cases/metadata.text +++ b/test/tm-cases/metadata.text @@ -23,6 +23,7 @@ adict: if linebreaks and indent are respected ! - subkey: and another dict in a list + - but one-liners remains: simple strings --- # The real text From e30cedc351405545fa180aa4385edbaca05a97c6 Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Fri, 27 Nov 2020 17:59:24 -0500 Subject: [PATCH 056/477] Update CHANGES.md --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index af657f00..809e602c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,7 +2,7 @@ ## python-markdown2 2.4.0 (not yet released) -(nothing yet) +- [pull #377] Fixed bug breaking strings elements in metadata lists ## python-markdown2 2.3.10 From 94250dc2bcaf3ff9a7be4b4d72a017aefec037d8 Mon Sep 17 00:00:00 2001 From: Ben North Date: Fri, 27 Nov 2020 23:48:53 +0000 Subject: [PATCH 057/477] _incomplete_tags_re: Use raw string --- lib/markdown2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/markdown2.py b/lib/markdown2.py index 56dd2f11..e87ff92f 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -2232,7 +2232,7 @@ def _encode_amps_and_angles(self, text): text = self._naked_gt_re.sub('>', text) return text - _incomplete_tags_re = re.compile("<(/?\w+?(?!\w).+?[\s/]+?)") + _incomplete_tags_re = re.compile(r"<(/?\w+?(?!\w).+?[\s/]+?)") def _encode_incomplete_tags(self, text): if self.safe_mode not in ("replace", "escape"): From 7b63eb1b17845fcfc7f0f886113a6e784f8bf056 Mon Sep 17 00:00:00 2001 From: Ben North Date: Fri, 27 Nov 2020 23:49:09 +0000 Subject: [PATCH 058/477] _python_ver_from_python(): Use raw string --- test/testall.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testall.py b/test/testall.py index b2047887..689fe5c0 100644 --- a/test/testall.py +++ b/test/testall.py @@ -20,7 +20,7 @@ def _python_ver_from_python(python): assert ' ' not in python o = os.popen('''%s -c "import sys; print(sys.version)"''' % python) ver_str = o.read().strip() - ver_bits = re.split("\.|[^\d]", ver_str, 2)[:2] + ver_bits = re.split(r"\.|[^\d]", ver_str, 2)[:2] ver = tuple(map(int, ver_bits)) return ver From 7f12db69b841a72dab9a1097a1743a9b309d6e5a Mon Sep 17 00:00:00 2001 From: Denis Kasak Date: Wed, 16 Dec 2020 16:00:45 +0100 Subject: [PATCH 059/477] When rendering fenced code blocks, add `language-LANG` class as well. This enables better interoperability because other tools usually expect this class when the language is specified for a code block (see: https://html.spec.whatwg.org/multipage/text-level-semantics.html#the-code-element). Fixes #370. --- lib/markdown2.py | 2 +- test/tm-cases/highlightjs_lang.html | 14 ++++---------- test/tm-cases/highlightjs_lang.text | 8 -------- 3 files changed, 5 insertions(+), 19 deletions(-) diff --git a/lib/markdown2.py b/lib/markdown2.py index e87ff92f..bb5260be 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -1884,7 +1884,7 @@ def unhash_code(codeblock): pre_class_str = self._html_class_str_from_tag("pre") if "highlightjs-lang" in self.extras and lexer_name: - code_class_str = ' class="%s"' % lexer_name + code_class_str = ' class="%s language-%s"' % (lexer_name, lexer_name) else: code_class_str = self._html_class_str_from_tag("code") diff --git a/test/tm-cases/highlightjs_lang.html b/test/tm-cases/highlightjs_lang.html index 2ca1490a..6a691b45 100644 --- a/test/tm-cases/highlightjs_lang.html +++ b/test/tm-cases/highlightjs_lang.html @@ -1,23 +1,17 @@ -
here is some cpp code
+
here is some cpp code
 
-
some lang-cpp code
-
- -
and some language-cpp code
-
- -
some code without highlighting
+
some code without highlighting
 

That's using the fenced-code-blocks and highlightjs-lang extra.

Here is an empty one (just to check):

-

+

 

Here is one at the end of the file:

-
    is indentation maintained?
+
    is indentation maintained?
 
diff --git a/test/tm-cases/highlightjs_lang.text b/test/tm-cases/highlightjs_lang.text index 9073ed34..b1c5882c 100644 --- a/test/tm-cases/highlightjs_lang.text +++ b/test/tm-cases/highlightjs_lang.text @@ -2,14 +2,6 @@ here is some cpp code ``` -```lang-cpp -some lang-cpp code -``` - -```language-cpp -and some language-cpp code -``` - ```nohighlight some code without highlighting ``` From de877aa59c0cf5ad94dd2959e746f9945df650b8 Mon Sep 17 00:00:00 2001 From: Denis Kasak Date: Wed, 16 Dec 2020 16:04:46 +0100 Subject: [PATCH 060/477] Update CHANGES/CONTRIBUTORS. --- CHANGES.md | 1 + CONTRIBUTORS.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 809e602c..76f8412c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,7 @@ ## python-markdown2 2.4.0 (not yet released) - [pull #377] Fixed bug breaking strings elements in metadata lists +- [pull #380] When rendering fenced code blocks, also add the `language-LANG` class ## python-markdown2 2.3.10 diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index e318051e..9312b1b8 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -47,3 +47,4 @@ Gareth Simpson (github.com/xurble) Kat Hagan (github.com/codebykat) Stɑrry Shivɑm (github.com/starry69) André Nasturas (github.com/andrenasturas) +Denis Kasak (github.com/dkasak) From 01400f42fc5273a003f40bc95770146a4dad0d7b Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Fri, 18 Dec 2020 18:15:38 -0500 Subject: [PATCH 061/477] Revert "Fix for Pygments version bump in tests" This reverts commit 3abfc5f5fd8099e337bfefd4d12923d04de414ef. --- test/tm-cases/syntax_color_opts.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/tm-cases/syntax_color_opts.html b/test/tm-cases/syntax_color_opts.html index 13d69956..5c928c2d 100644 --- a/test/tm-cases/syntax_color_opts.html +++ b/test/tm-cases/syntax_color_opts.html @@ -1,6 +1,6 @@

Here is some sample code:

-
import sys
+
import sys
 def main(argv=sys.argv):
     logging.basicConfig()
     log.info('hi')
@@ -8,7 +8,7 @@
 
 

and:

-
use 'zlib'
+
use 'zlib'
 sub main(argv)
     puts 'hi'
 end

From b9e3ec711890ec10234136ba71a94ac0e62607ed Mon Sep 17 00:00:00 2001
From: Nicholas Serra 
Date: Fri, 18 Dec 2020 18:17:25 -0500
Subject: [PATCH 062/477] Pygments test fix for new version

---
 test/tm-cases/syntax_color_opts.html | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/test/tm-cases/syntax_color_opts.html b/test/tm-cases/syntax_color_opts.html
index 5c928c2d..a44e49d2 100644
--- a/test/tm-cases/syntax_color_opts.html
+++ b/test/tm-cases/syntax_color_opts.html
@@ -1,6 +1,6 @@
 

Here is some sample code:

-
import sys
+
import sys
 def main(argv=sys.argv):
     logging.basicConfig()
     log.info('hi')
@@ -8,7 +8,7 @@
 
 

and:

-
use 'zlib'
+
use 'zlib'
 sub main(argv)
     puts 'hi'
 end

From b98813fb64972a4369fde79c6609f130453b913e Mon Sep 17 00:00:00 2001
From: Tim Gates 
Date: Fri, 25 Dec 2020 20:35:44 +1100
Subject: [PATCH 063/477] docs: fix simple typo, becase -> because

There is a small typo in test/testlib.py.

Should read `because` rather than `becase`.
---
 test/testlib.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/testlib.py b/test/testlib.py
index d753f9ee..06015404 100644
--- a/test/testlib.py
+++ b/test/testlib.py
@@ -113,7 +113,7 @@ def decorate(f):
 #---- timedtest decorator
 # Use this to assert that a test completes in a given amount of time.
 # This is from http://www.artima.com/forums/flat.jsp?forum=122&thread=129497
-# Including here, becase it might be useful.
+# Including here, because it might be useful.
 # NOTE: Untested and I suspect some breakage.
 
 TOLERANCE = 0.05

From 96dff22341489459c8cb832fdfd066a588ec23bf Mon Sep 17 00:00:00 2001
From: Nicholas Serra 
Date: Wed, 20 Jan 2021 17:23:21 -0500
Subject: [PATCH 064/477] Regex DOS fixes

---
 lib/markdown2.py | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/lib/markdown2.py b/lib/markdown2.py
index bb5260be..f3e41cc1 100755
--- a/lib/markdown2.py
+++ b/lib/markdown2.py
@@ -532,7 +532,7 @@ def parse_structured_value(value):
 
         return tail
 
-    _emacs_oneliner_vars_pat = re.compile(r"-\*-\s*([^\r\n]*?)\s*-\*-", re.UNICODE)
+    _emacs_oneliner_vars_pat = re.compile(r"-\*-\s*(?:(\S[^\r\n]*?)([\r\n]\s*)?)?-\*-", re.UNICODE)
     # This regular expression is intended to match blocks like this:
     #    PREFIX Local Variables: SUFFIX
     #    PREFIX mode: Tcl SUFFIX
@@ -892,8 +892,8 @@ def _do_numbering(self, text):
         '''
         # First pass to define all the references
         self.regex_defns = re.compile(r'''
-            \[\#(\w+)\s* # the counter.  Open square plus hash plus a word \1
-            ([^@]*)\s*   # Some optional characters, that aren't an @. \2
+            \[\#(\w+) # the counter.  Open square plus hash plus a word \1
+            ([^@]*)   # Some optional characters, that aren't an @. \2
             @(\w+)       # the id.  Should this be normed? \3
             ([^\]]*)\]   # The rest of the text up to the terminating ] \4
             ''', re.VERBOSE)
@@ -908,7 +908,7 @@ def _do_numbering(self, text):
             if len(match.groups()) != 4:
                 continue
             counter = match.group(1)
-            text_before = match.group(2)
+            text_before = match.group(2).strip()
             ref_id = match.group(3)
             text_after = match.group(4)
             number = counters.get(counter, 1)
@@ -1926,7 +1926,7 @@ def _do_code_blocks(self, text):
 
     _fenced_code_block_re = re.compile(r'''
         (?:\n+|\A\n?)
-        ^```\s*?([\w+-]+)?\s*?\n    # opening fence, $1 = optional lang
+        ^```\s{0,2}([\w+-]+)?\s*?\n     # opening fence, $1 = optional lang
         (.*?)                       # $2 = code block content
         ^```[ \t]*\n                # closing fence
         ''', re.M | re.X | re.S)

From e1954d3a345fc7a4ccc113bd58f7df81ad63b6ec Mon Sep 17 00:00:00 2001
From: Nicholas Serra 
Date: Wed, 20 Jan 2021 17:27:21 -0500
Subject: [PATCH 065/477] Pretty comment alignment

---
 lib/markdown2.py | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/lib/markdown2.py b/lib/markdown2.py
index f3e41cc1..61bb6f69 100755
--- a/lib/markdown2.py
+++ b/lib/markdown2.py
@@ -1926,9 +1926,9 @@ def _do_code_blocks(self, text):
 
     _fenced_code_block_re = re.compile(r'''
         (?:\n+|\A\n?)
-        ^```\s{0,2}([\w+-]+)?\s*?\n     # opening fence, $1 = optional lang
-        (.*?)                       # $2 = code block content
-        ^```[ \t]*\n                # closing fence
+        ^```\s{0,2}([\w+-]+)?\s*?\n  # opening fence, $1 = optional lang
+        (.*?)                        # $2 = code block content
+        ^```[ \t]*\n                 # closing fence
         ''', re.M | re.X | re.S)
 
     def _fenced_code_block_sub(self, match):

From c4b4ccb3f9da33f29b013d6d765fd223a8277cfe Mon Sep 17 00:00:00 2001
From: Nicholas Serra 
Date: Wed, 20 Jan 2021 18:28:54 -0500
Subject: [PATCH 066/477] Be forgiving

---
 lib/markdown2.py | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/lib/markdown2.py b/lib/markdown2.py
index 61bb6f69..61b22006 100755
--- a/lib/markdown2.py
+++ b/lib/markdown2.py
@@ -1926,9 +1926,9 @@ def _do_code_blocks(self, text):
 
     _fenced_code_block_re = re.compile(r'''
         (?:\n+|\A\n?)
-        ^```\s{0,2}([\w+-]+)?\s*?\n  # opening fence, $1 = optional lang
-        (.*?)                        # $2 = code block content
-        ^```[ \t]*\n                 # closing fence
+        ^```\s{0,99}([\w+-]+)?\s{0,99}\n  # opening fence, $1 = optional lang
+        (.*?)                             # $2 = code block content
+        ^```[ \t]*\n                      # closing fence
         ''', re.M | re.X | re.S)
 
     def _fenced_code_block_sub(self, match):

From 887e958866db430b1a2d7c22b066131af0accd32 Mon Sep 17 00:00:00 2001
From: Nicholas Serra 
Date: Wed, 20 Jan 2021 23:49:17 -0500
Subject: [PATCH 067/477] Update CHANGES.md

---
 CHANGES.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CHANGES.md b/CHANGES.md
index 76f8412c..1c9a40cc 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -4,6 +4,7 @@
 
 - [pull #377] Fixed bug breaking strings elements in metadata lists
 - [pull #380] When rendering fenced code blocks, also add the `language-LANG` class
+- [pull #387] Regex DoS fixes
 
 
 ## python-markdown2 2.3.10

From 31491857f247f553c4006b7ef55823deefb9e8e9 Mon Sep 17 00:00:00 2001
From: Nicholas Serra 
Date: Fri, 22 Jan 2021 15:48:03 -0500
Subject: [PATCH 068/477] prepare for 2.4.0 release

---
 CHANGES.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CHANGES.md b/CHANGES.md
index 1c9a40cc..22ba1898 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,6 +1,6 @@
 # python-markdown2 Changelog
 
-## python-markdown2 2.4.0 (not yet released)
+## python-markdown2 2.4.0
 
 - [pull #377] Fixed bug breaking strings elements in metadata lists
 - [pull #380] When rendering fenced code blocks, also add the `language-LANG` class

From 1ce2ac65ad5a32e914d814d129f7ef983baf408d Mon Sep 17 00:00:00 2001
From: Nicholas Serra 
Date: Fri, 22 Jan 2021 15:53:29 -0500
Subject: [PATCH 069/477] prep for future dev

---
 CHANGES.md | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/CHANGES.md b/CHANGES.md
index 22ba1898..232ffc57 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,5 +1,10 @@
 # python-markdown2 Changelog
 
+## python-markdown2 2.4.1 (not yet released)
+
+(nothing yet)
+
+
 ## python-markdown2 2.4.0
 
 - [pull #377] Fixed bug breaking strings elements in metadata lists

From 5398362bc312da4872fe63cc84b4717f172149ea Mon Sep 17 00:00:00 2001
From: Nicholas Serra 
Date: Fri, 22 Jan 2021 15:57:43 -0500
Subject: [PATCH 070/477] prep for future dev

---
 lib/markdown2.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/markdown2.py b/lib/markdown2.py
index 61b22006..98e76d5c 100755
--- a/lib/markdown2.py
+++ b/lib/markdown2.py
@@ -97,7 +97,7 @@
 #   not yet sure if there implications with this. Compare 'pydoc sre'
 #   and 'perldoc perlre'.
 
-__version_info__ = (2, 4, 0)
+__version_info__ = (2, 4, 1)
 __version__ = '.'.join(map(str, __version_info__))
 __author__ = "Trent Mick"
 

From de7fe0b119ae93906b468a83a46789501661b028 Mon Sep 17 00:00:00 2001
From: Kat Hagan 
Date: Wed, 3 Feb 2021 22:27:34 -0800
Subject: [PATCH 071/477] tables: allow whitespace at the end of the underline
 row

---
 lib/markdown2.py                          |  4 ++--
 test/php-markdown-extra-cases/Tables.html | 21 +++++++++++++++++++++
 test/php-markdown-extra-cases/Tables.text |  7 +++++++
 3 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/lib/markdown2.py b/lib/markdown2.py
index 98e76d5c..f57ed0be 100755
--- a/lib/markdown2.py
+++ b/lib/markdown2.py
@@ -1113,10 +1113,10 @@ def _do_tables(self, text):
                 ^[ ]{0,%d}                      # allowed whitespace
                 (                               # $2: underline row
                     # underline row with leading bar
-                    (?:  \|\ *:?-+:?\ *  )+  \|?  \n
+                    (?:  \|\ *:?-+:?\ *  )+  \|? \s? \n
                     |
                     # or, underline row without leading bar
-                    (?:  \ *:?-+:?\ *\|  )+  (?:  \ *:?-+:?\ *  )?  \n
+                    (?:  \ *:?-+:?\ *\|  )+  (?:  \ *:?-+:?\ *  )? \s? \n
                 )
 
                 (                               # $3: data rows
diff --git a/test/php-markdown-extra-cases/Tables.html b/test/php-markdown-extra-cases/Tables.html
index 95b9c2a9..92b6a5aa 100644
--- a/test/php-markdown-extra-cases/Tables.html
+++ b/test/php-markdown-extra-cases/Tables.html
@@ -308,3 +308,24 @@ 

Missing tailing pipe

+ +

With a space at the end of the underline row

+ + + + + + + + + + + + + + + + + + +
Header 1Header 2
Cell 1Cell 2
Cell 3Cell 4
diff --git a/test/php-markdown-extra-cases/Tables.text b/test/php-markdown-extra-cases/Tables.text index b761ad91..1c1d31cb 100644 --- a/test/php-markdown-extra-cases/Tables.text +++ b/test/php-markdown-extra-cases/Tables.text @@ -101,3 +101,10 @@ Header 1 | Header 2 | --------- | --------- | Cell | Cell | Cell | Cell + +# With a space at the end of the underline row + +Header 1 | Header 2 | +--------- | --------- | +Cell 1 | Cell 2 | +Cell 3 | Cell 4 | From 921d9983734429138b107a6bc5388bd4a90fdd7f Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Thu, 4 Feb 2021 13:54:16 -0500 Subject: [PATCH 072/477] Update CHANGES.md --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 232ffc57..9bd04c85 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,7 +2,7 @@ ## python-markdown2 2.4.1 (not yet released) -(nothing yet) +- [pull #389] Tables extra: allow whitespace at the end of the underline row ## python-markdown2 2.4.0 From 37ebca573159c25c110c0a387453b10129ce1688 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Fri, 12 Feb 2021 22:44:48 +0100 Subject: [PATCH 073/477] pyshell: add syntax highlighting --- CHANGES.md | 1 + lib/markdown2.py | 3 +++ .../pyshell_and_fenced_code_blocks.html | 21 +++++++++++++++++++ .../pyshell_and_fenced_code_blocks.opts | 1 + .../pyshell_and_fenced_code_blocks.tags | 1 + .../pyshell_and_fenced_code_blocks.text | 17 +++++++++++++++ 6 files changed, 44 insertions(+) create mode 100644 test/tm-cases/pyshell_and_fenced_code_blocks.html create mode 100644 test/tm-cases/pyshell_and_fenced_code_blocks.opts create mode 100644 test/tm-cases/pyshell_and_fenced_code_blocks.tags create mode 100644 test/tm-cases/pyshell_and_fenced_code_blocks.text diff --git a/CHANGES.md b/CHANGES.md index 9bd04c85..1cb89112 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,7 @@ ## python-markdown2 2.4.1 (not yet released) - [pull #389] Tables extra: allow whitespace at the end of the underline row +- [pull #392] Pyshell extra: enable syntax highlighting if `fenced-code-blocks` is loaded. ## python-markdown2 2.4.0 diff --git a/lib/markdown2.py b/lib/markdown2.py index f57ed0be..cfdb04c1 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -1029,6 +1029,9 @@ def _run_block_gamut(self, text): return text def _pyshell_block_sub(self, match): + if "fenced-code-blocks" in self.extras: + dedented = _dedent(match.group(0)) + return self._do_fenced_code_blocks("```pycon\n" + dedented + "```\n") lines = match.group(0).splitlines(0) _dedentlines(lines) indent = ' ' * self.tab_width diff --git a/test/tm-cases/pyshell_and_fenced_code_blocks.html b/test/tm-cases/pyshell_and_fenced_code_blocks.html new file mode 100644 index 00000000..a9fc2cf6 --- /dev/null +++ b/test/tm-cases/pyshell_and_fenced_code_blocks.html @@ -0,0 +1,21 @@ +

From Recipe 302035

+ +

Some examples:

+ +
>>> nprint(9876543210)
+'9 876 543 210'
+>>> nprint(987654321, period=1, delimiter=",")
+'9,8,7,6,5,4,3,2,1,0'
+
+ +

Indented a bit:

+ +
>>> 1 + 1
+2
+
+ +

Cuddled to previous para (and at end of document):

+ +
>>> 2 + 2
+4
+
diff --git a/test/tm-cases/pyshell_and_fenced_code_blocks.opts b/test/tm-cases/pyshell_and_fenced_code_blocks.opts new file mode 100644 index 00000000..ff194214 --- /dev/null +++ b/test/tm-cases/pyshell_and_fenced_code_blocks.opts @@ -0,0 +1 @@ +{"extras": ["pyshell", "fenced-code-blocks"]} diff --git a/test/tm-cases/pyshell_and_fenced_code_blocks.tags b/test/tm-cases/pyshell_and_fenced_code_blocks.tags new file mode 100644 index 00000000..a6296bc7 --- /dev/null +++ b/test/tm-cases/pyshell_and_fenced_code_blocks.tags @@ -0,0 +1 @@ +extra fenced-code-blocks pygments pyshell diff --git a/test/tm-cases/pyshell_and_fenced_code_blocks.text b/test/tm-cases/pyshell_and_fenced_code_blocks.text new file mode 100644 index 00000000..fc1eaae4 --- /dev/null +++ b/test/tm-cases/pyshell_and_fenced_code_blocks.text @@ -0,0 +1,17 @@ +# From Recipe 302035 + +Some examples: + +>>> nprint(9876543210) +'9 876 543 210' +>>> nprint(987654321, period=1, delimiter=",") +'9,8,7,6,5,4,3,2,1,0' + +Indented a bit: + + >>> 1 + 1 + 2 + +Cuddled to previous para (and at end of document): +>>> 2 + 2 +4 From e351f29d37307cb191877a269069636be6a9264d Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Sat, 13 Feb 2021 22:41:30 -0500 Subject: [PATCH 074/477] Update CONTRIBUTORS.txt --- CONTRIBUTORS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 9312b1b8..5620065e 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -48,3 +48,4 @@ Kat Hagan (github.com/codebykat) Stɑrry Shivɑm (github.com/starry69) André Nasturas (github.com/andrenasturas) Denis Kasak (github.com/dkasak) +Maximilian Hils (github.com/mhils) From faeabbf30506dbde3029dfd697a88965d0c1bcc8 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Tue, 16 Mar 2021 09:15:42 +0100 Subject: [PATCH 075/477] Travis CI: Upgrade to Python 3.10-dev Currently 3.10.0alpha6 --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 52d13a84..ead352ec 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,8 @@ python: - "3.6" - "3.7" - "3.8" - - "3.9-dev" + - "3.9" + - "3.10-dev" # command to install dependencies install: pip install Pygments>=2.5.2 # command to run tests From d6a56f4d438a74234f795a5a2b9b749342b3c362 Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Tue, 20 Jul 2021 23:05:18 -0400 Subject: [PATCH 076/477] Bandaid for regex dos --- lib/markdown2.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/markdown2.py b/lib/markdown2.py index cfdb04c1..13e294f3 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -1608,12 +1608,12 @@ def _toc_add_entry(self, level, id, name): self._toc.append((level, id, self._unescape_special_chars(name))) _h_re_base = r''' - (^(.+)[ \t]*\n(=+|-+)[ \t]*\n+) + (^(.+)[ \t]{0,99}\n(=+|-+)[ \t]*\n+) | (^(\#{1,6}) # \1 = string of #'s [ \t]%s (.+?) # \2 = Header text - [ \t]* + [ \t]{0,99} (? Date: Tue, 17 Aug 2021 22:29:39 -0400 Subject: [PATCH 077/477] Switch to github actions --- .github/python.yaml | 25 +++++++++++++++++++++++++ .travis.yml | 14 -------------- 2 files changed, 25 insertions(+), 14 deletions(-) create mode 100644 .github/python.yaml delete mode 100644 .travis.yml diff --git a/.github/python.yaml b/.github/python.yaml new file mode 100644 index 00000000..1e57cd6a --- /dev/null +++ b/.github/python.yaml @@ -0,0 +1,25 @@ +name: PythonCI +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] +jobs: + build: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: [pypy3, 3.5, 3.6, 3.7, 3.8, 3.9] + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install Pygments>=2.5.2 + - name: Test + run: | + make testone diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index ead352ec..00000000 --- a/.travis.yml +++ /dev/null @@ -1,14 +0,0 @@ -language: python -cache: pip -python: - - "pypy3" - - "3.5" - - "3.6" - - "3.7" - - "3.8" - - "3.9" - - "3.10-dev" -# command to install dependencies -install: pip install Pygments>=2.5.2 -# command to run tests -script: make testone From 91b4b4374d0db9126cdd712ee857ea00748666d4 Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Tue, 17 Aug 2021 22:31:27 -0400 Subject: [PATCH 078/477] Move file into workflows dir --- .github/{ => workflows}/python.yaml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/{ => workflows}/python.yaml (100%) diff --git a/.github/python.yaml b/.github/workflows/python.yaml similarity index 100% rename from .github/python.yaml rename to .github/workflows/python.yaml From b9fad6ca15be1b2ead3dacf93341cda20bedecc9 Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Tue, 17 Aug 2021 22:35:15 -0400 Subject: [PATCH 079/477] Cleanup --- README.md | 3 --- tox.ini | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/README.md b/README.md index 7c651636..e1d44f5c 100644 --- a/README.md +++ b/README.md @@ -28,9 +28,6 @@ your consideration. Follow @trentmick for updates to python-markdown2. -Travis-ci.org test status: [![Build Status](https://secure.travis-ci.org/trentm/python-markdown2.png)](http://travis-ci.org/trentm/python-markdown2) - - # Install To install it in your Python installation run *one* of the following: diff --git a/tox.ini b/tox.ini index aa1d1070..ec0ca9a5 100644 --- a/tox.ini +++ b/tox.ini @@ -4,7 +4,7 @@ # and then run "tox" from this directory. [tox] -envlist = py26, py27, py33, py34, py35, py36, py37, pypy, jython +envlist = py35, py36, py37, py38, py39, pypy [testenv] commands = make testone From 86b5f9bb8419281856cc139a71a9711258b7c94b Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Tue, 17 Aug 2021 22:41:49 -0400 Subject: [PATCH 080/477] Update CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 1cb89112..92a298be 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,6 +4,7 @@ - [pull #389] Tables extra: allow whitespace at the end of the underline row - [pull #392] Pyshell extra: enable syntax highlighting if `fenced-code-blocks` is loaded. +- [pull #402] Regex DOS bandaid fix ## python-markdown2 2.4.0 From 323f17bf5a05d08ef0a77198f8c7d8c7ccb543cc Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Tue, 17 Aug 2021 22:54:36 -0400 Subject: [PATCH 081/477] prepare for 2.4.1 release --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 92a298be..755553ed 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,6 @@ # python-markdown2 Changelog -## python-markdown2 2.4.1 (not yet released) +## python-markdown2 2.4.1 - [pull #389] Tables extra: allow whitespace at the end of the underline row - [pull #392] Pyshell extra: enable syntax highlighting if `fenced-code-blocks` is loaded. From 9a92311eea7cb4497908b91a8bf79cd7d9925b94 Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Tue, 17 Aug 2021 22:54:44 -0400 Subject: [PATCH 082/477] prep for future dev --- CHANGES.md | 5 +++++ lib/markdown2.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 755553ed..54943fbe 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,10 @@ # python-markdown2 Changelog +## python-markdown2 2.4.2 (not yet released) + +(nothing yet) + + ## python-markdown2 2.4.1 - [pull #389] Tables extra: allow whitespace at the end of the underline row diff --git a/lib/markdown2.py b/lib/markdown2.py index 13e294f3..ffb609a4 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -97,7 +97,7 @@ # not yet sure if there implications with this. Compare 'pydoc sre' # and 'perldoc perlre'. -__version_info__ = (2, 4, 1) +__version_info__ = (2, 4, 2) __version__ = '.'.join(map(str, __version_info__)) __author__ = "Trent Mick" From 05dd6a89134442e8bc3d49b0da482d87ca32b5d4 Mon Sep 17 00:00:00 2001 From: BarkeH Date: Sun, 19 Sep 2021 16:44:02 +1000 Subject: [PATCH 083/477] Fix issue #396 Fix to issue #396 --- lib/markdown2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/markdown2.py b/lib/markdown2.py index ffb609a4..6d060859 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -1929,7 +1929,7 @@ def _do_code_blocks(self, text): _fenced_code_block_re = re.compile(r''' (?:\n+|\A\n?) - ^```\s{0,99}([\w+-]+)?\s{0,99}\n # opening fence, $1 = optional lang + ^```\s{0,99}?([\w+-]+)?\s{0,99}?\n # opening fence, $1 = optional lang (.*?) # $2 = code block content ^```[ \t]*\n # closing fence ''', re.M | re.X | re.S) From e28fc46c558230ea62e3104b587f864fdcaeb3a6 Mon Sep 17 00:00:00 2001 From: BarkeH Date: Sun, 19 Sep 2021 16:55:27 +1000 Subject: [PATCH 084/477] Fenced code blocks issue #396 regression test --- test/tm-cases/fenced_code_blocks_issue396.html | 4 ++++ test/tm-cases/fenced_code_blocks_issue396.opts | 1 + test/tm-cases/fenced_code_blocks_issue396.text | 5 +++++ 3 files changed, 10 insertions(+) create mode 100644 test/tm-cases/fenced_code_blocks_issue396.html create mode 100644 test/tm-cases/fenced_code_blocks_issue396.opts create mode 100644 test/tm-cases/fenced_code_blocks_issue396.text diff --git a/test/tm-cases/fenced_code_blocks_issue396.html b/test/tm-cases/fenced_code_blocks_issue396.html new file mode 100644 index 00000000..8a277829 --- /dev/null +++ b/test/tm-cases/fenced_code_blocks_issue396.html @@ -0,0 +1,4 @@ +
a
+b
+c
+
diff --git a/test/tm-cases/fenced_code_blocks_issue396.opts b/test/tm-cases/fenced_code_blocks_issue396.opts new file mode 100644 index 00000000..91560387 --- /dev/null +++ b/test/tm-cases/fenced_code_blocks_issue396.opts @@ -0,0 +1 @@ +{"extras": ["fenced-code-blocks"]} \ No newline at end of file diff --git a/test/tm-cases/fenced_code_blocks_issue396.text b/test/tm-cases/fenced_code_blocks_issue396.text new file mode 100644 index 00000000..041d79eb --- /dev/null +++ b/test/tm-cases/fenced_code_blocks_issue396.text @@ -0,0 +1,5 @@ +``` +a +b +c +``` \ No newline at end of file From bd707a84175242bc464e8eae48c1e24d03fc93d6 Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Mon, 27 Sep 2021 20:48:11 -0400 Subject: [PATCH 085/477] Changes and contributors --- CHANGES.md | 2 +- CONTRIBUTORS.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 54943fbe..d79074c8 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,7 +2,7 @@ ## python-markdown2 2.4.2 (not yet released) -(nothing yet) +- [pull #408] Fix for fenced code blocks issue #396 ## python-markdown2 2.4.1 diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 5620065e..09fe9626 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -49,3 +49,4 @@ Stɑrry Shivɑm (github.com/starry69) André Nasturas (github.com/andrenasturas) Denis Kasak (github.com/dkasak) Maximilian Hils (github.com/mhils) +BarkeH (github.com/BarkeH) From b634a6dafc20dd39caeaabec16c00bf75f01363a Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Fri, 15 Oct 2021 20:07:34 -0400 Subject: [PATCH 086/477] Be more strict on auto linking url --- lib/markdown2.py | 2 +- test/tm-cases/issue341_xss.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/markdown2.py b/lib/markdown2.py index 6d060859..634c0987 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -1235,7 +1235,7 @@ def _run_span_gamut(self, text): \s*/?> | # auto-link (e.g., ) - <\w+[^>]*> + <[\w~:/?#\[\]@!$&'\(\)*+,;%=\.\\-]+> | # comment | diff --git a/test/tm-cases/issue341_xss.html b/test/tm-cases/issue341_xss.html index 48aedff9..c51acb3d 100644 --- a/test/tm-cases/issue341_xss.html +++ b/test/tm-cases/issue341_xss.html @@ -2,4 +2,4 @@ [HTML_REMOVED]alert(1);//>[HTML_REMOVED]>

Example 2: -[HTML_REMOVED]alert(1);/*->a>a\\*/[HTML_REMOVED]alert(1);/*->a>

+<http://g[HTML_REMOVED]alert(1);/\*->a><http://ga\\*/[HTML_REMOVED]alert(1);/*->a>

From db33636f96129748e5208bb54d5864df8a6ea275 Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Wed, 1 Dec 2021 22:24:13 -0500 Subject: [PATCH 087/477] Update CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index d79074c8..f26ff577 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,7 @@ ## python-markdown2 2.4.2 (not yet released) - [pull #408] Fix for fenced code blocks issue #396 +- [pull #410] Be more strict on auto linking urls, RE DOS fix ## python-markdown2 2.4.1 From 79fdd50a55ea47e2246a1269c21611fb14d7fff9 Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Wed, 1 Dec 2021 22:50:38 -0500 Subject: [PATCH 088/477] prepare for 2.4.2 release --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index f26ff577..935f210b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,6 @@ # python-markdown2 Changelog -## python-markdown2 2.4.2 (not yet released) +## python-markdown2 2.4.2 - [pull #408] Fix for fenced code blocks issue #396 - [pull #410] Be more strict on auto linking urls, RE DOS fix From 24365bc9ed059b4b44f6008c796852635597d9e2 Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Wed, 1 Dec 2021 22:50:55 -0500 Subject: [PATCH 089/477] prep for future dev --- CHANGES.md | 5 +++++ lib/markdown2.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 935f210b..2df9a681 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,10 @@ # python-markdown2 Changelog +## python-markdown2 2.4.3 (not yet released) + +(nothing yet) + + ## python-markdown2 2.4.2 - [pull #408] Fix for fenced code blocks issue #396 diff --git a/lib/markdown2.py b/lib/markdown2.py index 634c0987..fdc296db 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -97,7 +97,7 @@ # not yet sure if there implications with this. Compare 'pydoc sre' # and 'perldoc perlre'. -__version_info__ = (2, 4, 2) +__version_info__ = (2, 4, 3) __version__ = '.'.join(map(str, __version_info__)) __author__ = "Trent Mick" From 28f210c8d4ec9193b72197d5c730abc49d475762 Mon Sep 17 00:00:00 2001 From: antonio Date: Tue, 1 Feb 2022 22:03:55 -0500 Subject: [PATCH 090/477] dedent multiline meta text --- lib/markdown2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/markdown2.py b/lib/markdown2.py index fdc296db..03020fac 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -516,7 +516,7 @@ def parse_structured_value(value): # Multiline value if v[:3] == " >\n": - self.metadata[k.strip()] = v[3:].strip() + self.metadata[k.strip()] = _dedent(v[3:]).strip() # Empty value elif v == "\n": From b969f4128a0f5931b1395c0ad25e783ebfab3267 Mon Sep 17 00:00:00 2001 From: antonio Date: Tue, 1 Feb 2022 22:04:21 -0500 Subject: [PATCH 091/477] add test case --- test/tm-cases/metadata.metadata | 2 +- test/tm-cases/metadata.text | 1 + test/tm-cases/metadata2.metadata | 2 +- test/tm-cases/metadata2.text | 1 + 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/test/tm-cases/metadata.metadata b/test/tm-cases/metadata.metadata index 1ee2c4fe..a0180539 100644 --- a/test/tm-cases/metadata.metadata +++ b/test/tm-cases/metadata.metadata @@ -4,7 +4,7 @@ "And": "some, cvs, data, which, you, must, parse, yourself", "this-is": "a hyphen test", "empty": "", - "and some": "long value\n that goes multiline", + "and some": "long value\n with complex indentation\nthat goes multiline", "another": "example", "alist": ["a", "b", "c"], "adict": {"key": "foo", "a nested list": ["one", "two", "Even multiline strings are allowed\n in nested structured data\n if linebreaks and indent are respected !", {"subkey": "and another dict in a list"}, "but one-liners remains: simple strings"]} diff --git a/test/tm-cases/metadata.text b/test/tm-cases/metadata.text index c12494df..60dc7b15 100644 --- a/test/tm-cases/metadata.text +++ b/test/tm-cases/metadata.text @@ -6,6 +6,7 @@ this-is : a hyphen test empty : and some: > long value + with complex indentation that goes multiline another: example alist: diff --git a/test/tm-cases/metadata2.metadata b/test/tm-cases/metadata2.metadata index 172822d9..3b392f62 100644 --- a/test/tm-cases/metadata2.metadata +++ b/test/tm-cases/metadata2.metadata @@ -4,6 +4,6 @@ "And": "some, cvs, data, which, you, must, parse, yourself", "this-is": "a hyphen test", "empty": "", - "another long": "long value\n that goes multiline", + "another long": "long value\n with complex indentation\nthat goes multiline", "another": "example" } diff --git a/test/tm-cases/metadata2.text b/test/tm-cases/metadata2.text index 13579f12..b59d3121 100644 --- a/test/tm-cases/metadata2.text +++ b/test/tm-cases/metadata2.text @@ -5,6 +5,7 @@ this-is : a hyphen test empty : another long: > long value + with complex indentation that goes multiline another: example From cd2957733bd82f69a3c87fafb4d9becf1e9cd605 Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Sat, 5 Feb 2022 15:01:59 -0500 Subject: [PATCH 092/477] Changes and contributors --- CHANGES.md | 2 +- CONTRIBUTORS.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 2df9a681..7c318bbb 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,7 +2,7 @@ ## python-markdown2 2.4.3 (not yet released) -(nothing yet) +- [pull #413] Fix meta indentation ## python-markdown2 2.4.2 diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 09fe9626..299b97d2 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -50,3 +50,4 @@ André Nasturas (github.com/andrenasturas) Denis Kasak (github.com/dkasak) Maximilian Hils (github.com/mhils) BarkeH (github.com/BarkeH) +cav71 (github.com/cav71) From cb22a18aa58381a4898ab23d85b1143bfef14c91 Mon Sep 17 00:00:00 2001 From: Crozzers Date: Wed, 9 Feb 2022 12:24:35 +0000 Subject: [PATCH 093/477] Fix code surrounded by blank lines inside quoted fenced code blocks being treated as another code block. If you were using the `fenced-code-blocks` extension and you had code that was indented (eg: inside an if statement) and surrounded by blank lines, it would be detected as a code block, regardless of whether it was already inside a code block. EG: > ```python > if True: > print() > > print() # this line would register as a code block > > print() > ``` This is because the regex look-ahead being used to check for a `
` tag would only check the next HTML tag it found, which would usually be a `` tag if syntax highlighting was being used. The new look-ahead checks the next HTML tag that isn't a `` tag to see if it's a `
` tag --- lib/markdown2.py | 2 +- ...ode_blocks_whitespace_around_indented_lines.html | 13 +++++++++++++ ...ode_blocks_whitespace_around_indented_lines.opts | 1 + ...ode_blocks_whitespace_around_indented_lines.tags | 1 + ...ode_blocks_whitespace_around_indented_lines.text | 12 ++++++++++++ 5 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 test/tm-cases/quoted_fenced_code_blocks_whitespace_around_indented_lines.html create mode 100644 test/tm-cases/quoted_fenced_code_blocks_whitespace_around_indented_lines.opts create mode 100644 test/tm-cases/quoted_fenced_code_blocks_whitespace_around_indented_lines.tags create mode 100644 test/tm-cases/quoted_fenced_code_blocks_whitespace_around_indented_lines.text diff --git a/lib/markdown2.py b/lib/markdown2.py index 03020fac..0680bcc3 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -1922,7 +1922,7 @@ def _do_code_blocks(self, text): ((?=^[ ]{0,%d}\S)|\Z) # Lookahead for non-space at line-start, or end of doc # Lookahead to make sure this block isn't already in a code block. # Needed when syntax highlighting is being used. - (?![^<]*\) + (?!([^<]|<(/?)span)*\) ''' % (self.tab_width, self.tab_width), re.M | re.X) return code_block_re.sub(self._code_block_sub, text) diff --git a/test/tm-cases/quoted_fenced_code_blocks_whitespace_around_indented_lines.html b/test/tm-cases/quoted_fenced_code_blocks_whitespace_around_indented_lines.html new file mode 100644 index 00000000..6f344f05 --- /dev/null +++ b/test/tm-cases/quoted_fenced_code_blocks_whitespace_around_indented_lines.html @@ -0,0 +1,13 @@ +

Example:

+ +
+
if True:
+    print()
+
+    print()
+
+    print()
+
+    print()
+
+
diff --git a/test/tm-cases/quoted_fenced_code_blocks_whitespace_around_indented_lines.opts b/test/tm-cases/quoted_fenced_code_blocks_whitespace_around_indented_lines.opts new file mode 100644 index 00000000..91560387 --- /dev/null +++ b/test/tm-cases/quoted_fenced_code_blocks_whitespace_around_indented_lines.opts @@ -0,0 +1 @@ +{"extras": ["fenced-code-blocks"]} \ No newline at end of file diff --git a/test/tm-cases/quoted_fenced_code_blocks_whitespace_around_indented_lines.tags b/test/tm-cases/quoted_fenced_code_blocks_whitespace_around_indented_lines.tags new file mode 100644 index 00000000..12bca88c --- /dev/null +++ b/test/tm-cases/quoted_fenced_code_blocks_whitespace_around_indented_lines.tags @@ -0,0 +1 @@ +extra fenced-code-blocks pygments \ No newline at end of file diff --git a/test/tm-cases/quoted_fenced_code_blocks_whitespace_around_indented_lines.text b/test/tm-cases/quoted_fenced_code_blocks_whitespace_around_indented_lines.text new file mode 100644 index 00000000..a77adaca --- /dev/null +++ b/test/tm-cases/quoted_fenced_code_blocks_whitespace_around_indented_lines.text @@ -0,0 +1,12 @@ +### Example: + +> ```python +> if True: +> print() +> +> print() +> +> print() +> +> print() +> ``` \ No newline at end of file From 430349272fa16e523b3b75805fa87c3e7fc7f877 Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Mon, 14 Feb 2022 20:35:50 -0500 Subject: [PATCH 094/477] Changes and contributors --- CHANGES.md | 1 + CONTRIBUTORS.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 7c318bbb..f3e977d0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,7 @@ ## python-markdown2 2.4.3 (not yet released) - [pull #413] Fix meta indentation +- [pull #414] Fix code surrounded by blank lines inside blockquote fenced code blocks ## python-markdown2 2.4.2 diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 299b97d2..7d8a1574 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -51,3 +51,4 @@ Denis Kasak (github.com/dkasak) Maximilian Hils (github.com/mhils) BarkeH (github.com/BarkeH) cav71 (github.com/cav71) +Crozzers (github.com/Crozzers) From 82f1376238700be925f364dca87d64b5c6807617 Mon Sep 17 00:00:00 2001 From: Crozzers Date: Thu, 10 Mar 2022 15:44:43 +0000 Subject: [PATCH 095/477] Fix issue#399 --- lib/markdown2.py | 2 +- .../inline_code_pipe_within_table.html | 21 +++++++++++++++++++ .../inline_code_pipe_within_table.opts | 1 + .../inline_code_pipe_within_table.tags | 1 + .../inline_code_pipe_within_table.text | 4 ++++ 5 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 test/tm-cases/inline_code_pipe_within_table.html create mode 100644 test/tm-cases/inline_code_pipe_within_table.opts create mode 100644 test/tm-cases/inline_code_pipe_within_table.tags create mode 100644 test/tm-cases/inline_code_pipe_within_table.text diff --git a/lib/markdown2.py b/lib/markdown2.py index 0680bcc3..46dd38f2 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -1059,7 +1059,7 @@ def _prepare_pyshell_blocks(self, text): def _table_sub(self, match): trim_space_re = '^[ \t\n]+|[ \t\n]+$' trim_bar_re = r'^\||\|$' - split_bar_re = r'^\||(? + + + Sign + Operator name + Description + + + + + & + Bitwise and + Bitwise and between two integer values + + + | + Bitwise or + Bitwise or between two integer values + + + diff --git a/test/tm-cases/inline_code_pipe_within_table.opts b/test/tm-cases/inline_code_pipe_within_table.opts new file mode 100644 index 00000000..9625694e --- /dev/null +++ b/test/tm-cases/inline_code_pipe_within_table.opts @@ -0,0 +1 @@ +{"extras": ["tables"]} \ No newline at end of file diff --git a/test/tm-cases/inline_code_pipe_within_table.tags b/test/tm-cases/inline_code_pipe_within_table.tags new file mode 100644 index 00000000..8a4af592 --- /dev/null +++ b/test/tm-cases/inline_code_pipe_within_table.tags @@ -0,0 +1 @@ +extra tables \ No newline at end of file diff --git a/test/tm-cases/inline_code_pipe_within_table.text b/test/tm-cases/inline_code_pipe_within_table.text new file mode 100644 index 00000000..f1e8aa26 --- /dev/null +++ b/test/tm-cases/inline_code_pipe_within_table.text @@ -0,0 +1,4 @@ +| Sign | Operator name | Description | +|---|---|---| +| `&` | Bitwise and | Bitwise and between two integer values | +| `|` | Bitwise or | Bitwise or between two integer values | \ No newline at end of file From 678467428201d4625c2955add5ef33c7d2d8311e Mon Sep 17 00:00:00 2001 From: Crozzers Date: Thu, 10 Mar 2022 15:44:43 +0000 Subject: [PATCH 096/477] Fix issue#327 --- lib/markdown2.py | 10 ++++---- .../tm-cases/fenced_code_blocks_issue327.html | 22 ++++++++++++++++++ .../tm-cases/fenced_code_blocks_issue327.opts | 1 + .../tm-cases/fenced_code_blocks_issue327.tags | 1 + .../tm-cases/fenced_code_blocks_issue327.text | 23 +++++++++++++++++++ 5 files changed, 52 insertions(+), 5 deletions(-) create mode 100644 test/tm-cases/fenced_code_blocks_issue327.html create mode 100644 test/tm-cases/fenced_code_blocks_issue327.opts create mode 100644 test/tm-cases/fenced_code_blocks_issue327.tags create mode 100644 test/tm-cases/fenced_code_blocks_issue327.text diff --git a/lib/markdown2.py b/lib/markdown2.py index 0680bcc3..b444bf4d 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -1844,10 +1844,10 @@ def wrap(self, source, outfile): def _code_block_sub(self, match, is_fenced_code_block=False): lexer_name = None if is_fenced_code_block: - lexer_name = match.group(1) + lexer_name = match.group(2) if lexer_name: formatter_opts = self.extras['fenced-code-blocks'] or {} - codeblock = match.group(2) + codeblock = match.group(3) codeblock = codeblock[:-1] # drop one trailing newline else: codeblock = match.group(1) @@ -1929,9 +1929,9 @@ def _do_code_blocks(self, text): _fenced_code_block_re = re.compile(r''' (?:\n+|\A\n?) - ^```\s{0,99}?([\w+-]+)?\s{0,99}?\n # opening fence, $1 = optional lang - (.*?) # $2 = code block content - ^```[ \t]*\n # closing fence + (^`{3,})\s{0,99}?([\w+-]+)?\s{0,99}?\n # $1 = opening fence (captured for back-referencing), $2 = optional lang + (.*?) # $3 = code block content + \1[ \t]*\n # closing fence ''', re.M | re.X | re.S) def _fenced_code_block_sub(self, match): diff --git a/test/tm-cases/fenced_code_blocks_issue327.html b/test/tm-cases/fenced_code_blocks_issue327.html new file mode 100644 index 00000000..16cfc633 --- /dev/null +++ b/test/tm-cases/fenced_code_blocks_issue327.html @@ -0,0 +1,22 @@ +

Inner code blocks should not render as code blocks

+ +
```cpp
+int x = 10;
+```
+
+ +

Without language specifier

+ +
```
+int x = 10;
+```
+
+ +

Double nesting

+ +
````
+```cpp
+int x = 10;
+```
+````
+
diff --git a/test/tm-cases/fenced_code_blocks_issue327.opts b/test/tm-cases/fenced_code_blocks_issue327.opts new file mode 100644 index 00000000..91560387 --- /dev/null +++ b/test/tm-cases/fenced_code_blocks_issue327.opts @@ -0,0 +1 @@ +{"extras": ["fenced-code-blocks"]} \ No newline at end of file diff --git a/test/tm-cases/fenced_code_blocks_issue327.tags b/test/tm-cases/fenced_code_blocks_issue327.tags new file mode 100644 index 00000000..2d244483 --- /dev/null +++ b/test/tm-cases/fenced_code_blocks_issue327.tags @@ -0,0 +1 @@ +extra fenced-code-blocks \ No newline at end of file diff --git a/test/tm-cases/fenced_code_blocks_issue327.text b/test/tm-cases/fenced_code_blocks_issue327.text new file mode 100644 index 00000000..88ad0c68 --- /dev/null +++ b/test/tm-cases/fenced_code_blocks_issue327.text @@ -0,0 +1,23 @@ +Inner code blocks should not render as code blocks + +```` +```cpp +int x = 10; +``` +```` + +Without language specifier +```` +``` +int x = 10; +``` +```` + +Double nesting +````` +```` +```cpp +int x = 10; +``` +```` +````` \ No newline at end of file From 3d7261bb06de3aeae37596674c9b6528c59834ef Mon Sep 17 00:00:00 2001 From: Crozzers Date: Fri, 11 Mar 2022 15:57:39 +0000 Subject: [PATCH 097/477] Fix issue #400 --- lib/markdown2.py | 2 +- test/tm-cases/hr_uniform_characters.html | 48 +++++++++++++++++++++++ test/tm-cases/hr_uniform_characters.text | 49 ++++++++++++++++++++++++ 3 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 test/tm-cases/hr_uniform_characters.html create mode 100644 test/tm-cases/hr_uniform_characters.text diff --git a/lib/markdown2.py b/lib/markdown2.py index 0680bcc3..8afcb215 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -986,7 +986,7 @@ def _strip_footnote_definitions(self, text): re.X | re.M) return footnote_def_re.sub(self._extract_footnote_def_sub, text) - _hr_re = re.compile(r'^[ ]{0,3}([-_*][ ]{0,2}){3,}$', re.M) + _hr_re = re.compile(r'^[ ]{0,3}([-_*])[ ]{0,2}(\1[ ]{0,2}){2,}$', re.M) def _run_block_gamut(self, text): # These are all the transformations that form block-level diff --git a/test/tm-cases/hr_uniform_characters.html b/test/tm-cases/hr_uniform_characters.html new file mode 100644 index 00000000..2e5a7b95 --- /dev/null +++ b/test/tm-cases/hr_uniform_characters.html @@ -0,0 +1,48 @@ +

Horizontal rules should probably consist of all of the same characters +EG:

+ +
+ +

Or

+ +
+ +

Or

+ +
+ +

But not any of:

+ +

--*

+ +

-*-

+ +

-**

+ +

*--

+ +

-

+ +

**-

+ +

**_

+ +

_

+ +

*__

+ +

_**

+ +

*

+ +

__-

+ +

-

+ +

_--

+ +

-__

+ +

-_-

+ +

--_

diff --git a/test/tm-cases/hr_uniform_characters.text b/test/tm-cases/hr_uniform_characters.text new file mode 100644 index 00000000..8d5b69d8 --- /dev/null +++ b/test/tm-cases/hr_uniform_characters.text @@ -0,0 +1,49 @@ +Horizontal rules should probably consist of all of the same characters +EG: + +*** + +Or + +--- + +Or + +___ + + +But not any of: + +--* + +-*- + +-** + +*-- + +*-* + +**- + +**_ + +*_* + +*__ + +_** + +_*_ + +__- + +_-_ + +_-- + +-__ + +-_- + +--_ \ No newline at end of file From 8a009c93a52e3979864fb0b27a5e90e8a12136f1 Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Sun, 13 Mar 2022 21:22:03 -0400 Subject: [PATCH 098/477] Update CHANGES.md --- CHANGES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index f3e977d0..efaa9186 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -4,6 +4,9 @@ - [pull #413] Fix meta indentation - [pull #414] Fix code surrounded by blank lines inside blockquote fenced code blocks +- [pull #417] Fix inline code pipe symbol within tables (issue #399) +- [pull #418] Fix code block parsing error (issue #327) +- [pull #419] Fix hr block created when not supposed to (issue #400) ## python-markdown2 2.4.2 From bfb072e4eb8eb2d7324317e9e61eee1c7869dbd4 Mon Sep 17 00:00:00 2001 From: Crozzers Date: Tue, 15 Mar 2022 20:39:42 +0000 Subject: [PATCH 099/477] Fix #355 Issue was the regex for detecting fenced code blocks would detect the newline char preceding AND following the code block, meaning that code blocks seperated by a single newline char would not match as the regex wouldn't allow any overlapping. New regex uses a look-behind to find such newline chars --- lib/markdown2.py | 2 +- test/tm-cases/fenced_code_blocks_issue355.html | 10 ++++++++++ test/tm-cases/fenced_code_blocks_issue355.opts | 1 + test/tm-cases/fenced_code_blocks_issue355.tags | 1 + test/tm-cases/fenced_code_blocks_issue355.text | 10 ++++++++++ 5 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 test/tm-cases/fenced_code_blocks_issue355.html create mode 100644 test/tm-cases/fenced_code_blocks_issue355.opts create mode 100644 test/tm-cases/fenced_code_blocks_issue355.tags create mode 100644 test/tm-cases/fenced_code_blocks_issue355.text diff --git a/lib/markdown2.py b/lib/markdown2.py index cfbe3b92..0184b468 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -1928,7 +1928,7 @@ def _do_code_blocks(self, text): return code_block_re.sub(self._code_block_sub, text) _fenced_code_block_re = re.compile(r''' - (?:\n+|\A\n?) + (?:\n+|\A\n?|(?<=\n)) (^`{3,})\s{0,99}?([\w+-]+)?\s{0,99}?\n # $1 = opening fence (captured for back-referencing), $2 = optional lang (.*?) # $3 = code block content \1[ \t]*\n # closing fence diff --git a/test/tm-cases/fenced_code_blocks_issue355.html b/test/tm-cases/fenced_code_blocks_issue355.html new file mode 100644 index 00000000..66cc154e --- /dev/null +++ b/test/tm-cases/fenced_code_blocks_issue355.html @@ -0,0 +1,10 @@ +
some code block
+
+ +
yet another code block
+
+ +

new line:

+ +
code everywhere
+
diff --git a/test/tm-cases/fenced_code_blocks_issue355.opts b/test/tm-cases/fenced_code_blocks_issue355.opts new file mode 100644 index 00000000..91560387 --- /dev/null +++ b/test/tm-cases/fenced_code_blocks_issue355.opts @@ -0,0 +1 @@ +{"extras": ["fenced-code-blocks"]} \ No newline at end of file diff --git a/test/tm-cases/fenced_code_blocks_issue355.tags b/test/tm-cases/fenced_code_blocks_issue355.tags new file mode 100644 index 00000000..12bca88c --- /dev/null +++ b/test/tm-cases/fenced_code_blocks_issue355.tags @@ -0,0 +1 @@ +extra fenced-code-blocks pygments \ No newline at end of file diff --git a/test/tm-cases/fenced_code_blocks_issue355.text b/test/tm-cases/fenced_code_blocks_issue355.text new file mode 100644 index 00000000..c7e33b1c --- /dev/null +++ b/test/tm-cases/fenced_code_blocks_issue355.text @@ -0,0 +1,10 @@ +```python +some code block +``` +``` +yet another code block +``` +new line: +``` +code everywhere +``` \ No newline at end of file From f03c6dfcb02791c90948e36e1eab1f7b6fa8873d Mon Sep 17 00:00:00 2001 From: Crozzers Date: Tue, 15 Mar 2022 23:35:30 +0000 Subject: [PATCH 100/477] Fix #369 This should also probably fix #412 as well --- lib/markdown2.py | 5 +++-- test/tm-cases/backslash_removed_by_adjacent_backtick.html | 7 +++++++ test/tm-cases/backslash_removed_by_adjacent_backtick.text | 7 +++++++ 3 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 test/tm-cases/backslash_removed_by_adjacent_backtick.html create mode 100644 test/tm-cases/backslash_removed_by_adjacent_backtick.text diff --git a/lib/markdown2.py b/lib/markdown2.py index cfbe3b92..4e93eedf 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -256,6 +256,7 @@ def __init__(self, html4tags=False, tab_width=4, safe_mode=None, self.cli = cli self._escape_table = g_escape_table.copy() + self._code_table = {} if "smarty-pants" in self.extras: self._escape_table['"'] = _hash_text('"') self._escape_table["'"] = _hash_text("'") @@ -2005,7 +2006,7 @@ def _encode_code(self, text): for before, after in replacements: text = text.replace(before, after) hashed = _hash_text(text) - self._escape_table[text] = hashed + self._code_table[text] = hashed return hashed _strike_re = re.compile(r"~~(?=\S)(.+?)(?<=\S)~~", re.S) @@ -2335,7 +2336,7 @@ def _do_link_patterns(self, text): def _unescape_special_chars(self, text): # Swap back in all the special characters we've hidden. - for ch, hash in list(self._escape_table.items()): + for ch, hash in list(self._escape_table.items()) + list(self._code_table.items()): text = text.replace(hash, ch) return text diff --git a/test/tm-cases/backslash_removed_by_adjacent_backtick.html b/test/tm-cases/backslash_removed_by_adjacent_backtick.html new file mode 100644 index 00000000..1091b1a7 --- /dev/null +++ b/test/tm-cases/backslash_removed_by_adjacent_backtick.html @@ -0,0 +1,7 @@ +

hello \world

+ +

hello \world my favourite letter is w

+ +

hello \world my favourite code is import pickle

+ +

hello \world my favourite letter is x

diff --git a/test/tm-cases/backslash_removed_by_adjacent_backtick.text b/test/tm-cases/backslash_removed_by_adjacent_backtick.text new file mode 100644 index 00000000..4136c904 --- /dev/null +++ b/test/tm-cases/backslash_removed_by_adjacent_backtick.text @@ -0,0 +1,7 @@ +hello \world + +hello \world my favourite letter is `w` + +hello \world my favourite code is `import pickle` + +hello \world my favourite letter is `x` \ No newline at end of file From 6269c1f5f5e812f85ffb8524b8bf10b615579abf Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Tue, 22 Mar 2022 14:35:15 -0400 Subject: [PATCH 101/477] Update CHANGES.md --- CHANGES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index efaa9186..f133c924 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,6 +7,8 @@ - [pull #417] Fix inline code pipe symbol within tables (issue #399) - [pull #418] Fix code block parsing error (issue #327) - [pull #419] Fix hr block created when not supposed to (issue #400) +- [pull #421] Fix backslashes removed by adjacent code blocks (issues #369 and #412) +- [pull #420] Fix md5-* in resulting HTML when several code blocks follow one by one (issue #355) ## python-markdown2 2.4.2 From 4aa4d06d305c54c41d3a14832f7ac514d8a517a7 Mon Sep 17 00:00:00 2001 From: Crozzers Date: Wed, 23 Mar 2022 15:43:33 +0000 Subject: [PATCH 102/477] Fix excessive `
` tags in `ul` lists using `break-on-newline` extra (issue#396). --- lib/markdown2.py | 2 +- ...reak_on_newline_excessive_br_tags_in_ul.html | 17 +++++++++++++++++ ...reak_on_newline_excessive_br_tags_in_ul.opts | 1 + ...reak_on_newline_excessive_br_tags_in_ul.text | 8 ++++++++ 4 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 test/tm-cases/break_on_newline_excessive_br_tags_in_ul.html create mode 100644 test/tm-cases/break_on_newline_excessive_br_tags_in_ul.opts create mode 100644 test/tm-cases/break_on_newline_excessive_br_tags_in_ul.text diff --git a/lib/markdown2.py b/lib/markdown2.py index 500f5f68..c368278f 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -1220,7 +1220,7 @@ def _run_span_gamut(self, text): # Do hard breaks: if "break-on-newline" in self.extras: - text = re.sub(r" *\n", ")", "Conteúdo + +
    +
  • O que é estrutura Co-locada (on premises), o que é estrutura híbrida e o que é estrutura em-nuvem? +
      +
    • Em Nuvem (cloud based)
    • +
    • Uma estrutura em-nuvem tem todos os seus principais recursos providos por um provedor de serviços em nuvem. +
        +
      • Uma definição formal de serviço em nuvem pode ser:
      • +
      • Entrega via internet de um serviço de Tecnologia da Informação, sob demanda, em um modelo de pague-pelo-que-consome. +
          +
        • Brown Field é quando você migra um serviço existente
        • +
        • Green field é quando você começa do zero na nuvem, alguns também chamam isto de Cloud



        • +


      • +

    • +
  • +
diff --git a/test/tm-cases/break_on_newline_excessive_br_tags_in_ul.opts b/test/tm-cases/break_on_newline_excessive_br_tags_in_ul.opts new file mode 100644 index 00000000..a3d91cea --- /dev/null +++ b/test/tm-cases/break_on_newline_excessive_br_tags_in_ul.opts @@ -0,0 +1 @@ +{"extras": ["break-on-newline"]} \ No newline at end of file diff --git a/test/tm-cases/break_on_newline_excessive_br_tags_in_ul.text b/test/tm-cases/break_on_newline_excessive_br_tags_in_ul.text new file mode 100644 index 00000000..c8596478 --- /dev/null +++ b/test/tm-cases/break_on_newline_excessive_br_tags_in_ul.text @@ -0,0 +1,8 @@ +## Conteúdo +- O que é estrutura Co-locada (on premises), o que é estrutura híbrida e o que é estrutura em-nuvem? + - Em Nuvem (cloud based) + - Uma estrutura em-nuvem tem todos os seus principais recursos providos por um provedor de serviços em nuvem. + - Uma definição formal de serviço em nuvem pode ser: + - Entrega via internet de um serviço de Tecnologia da Informação, sob demanda, em um modelo de pague-pelo-que-consome. + - Brown Field é quando você migra um serviço existente + - Green field é quando você começa do zero na nuvem, alguns também chamam isto de Cloud \ No newline at end of file From 915b567875ea32c6f45a5d4ebdb16f29d93d042a Mon Sep 17 00:00:00 2001 From: Crozzers Date: Wed, 23 Mar 2022 16:04:01 +0000 Subject: [PATCH 103/477] Fix excessive `
` tags in `ol` lists and at the end of `ul` lists using `break-on-newline` extra --- lib/markdown2.py | 2 +- ...ak_on_newline_excessive_br_tags_in_ul.html | 43 +++++++++++++++++-- ...ak_on_newline_excessive_br_tags_in_ul.text | 19 +++++++- 3 files changed, 59 insertions(+), 5 deletions(-) diff --git a/lib/markdown2.py b/lib/markdown2.py index c368278f..beec36c9 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -1220,7 +1220,7 @@ def _run_span_gamut(self, text): # Do hard breaks: if "break-on-newline" in self.extras: - text = re.sub(r" *\n(?!\<(?:ul|li)\>)", ")", "Conteúdo
  • Entrega via internet de um serviço de Tecnologia da Informação, sob demanda, em um modelo de pague-pelo-que-consome.
    • Brown Field é quando você migra um serviço existente
    • -
    • Green field é quando você começa do zero na nuvem, alguns também chamam isto de Cloud



    • -


  • -
    +
  • Green field é quando você começa do zero na nuvem, alguns também chamam isto de Cloud
  • + + + +

    Ordered List

    + +
      +
    1. A +
        +
      1. B +
          +
        1. C +
            +
          1. D
          2. +
          3. E
          4. +
        2. +
      2. +
    2. +
    + +

    Mixed List

    + +
      +
    1. A +
        +
      • B +
          +
        1. C +
            +
          • D
          • +
          • E
          • +
        2. +
        3. F +
            +
          1. G
          2. +
          3. H
          4. +
        4. +
      • +
    2. +
    diff --git a/test/tm-cases/break_on_newline_excessive_br_tags_in_ul.text b/test/tm-cases/break_on_newline_excessive_br_tags_in_ul.text index c8596478..aacdd9be 100644 --- a/test/tm-cases/break_on_newline_excessive_br_tags_in_ul.text +++ b/test/tm-cases/break_on_newline_excessive_br_tags_in_ul.text @@ -5,4 +5,21 @@ - Uma definição formal de serviço em nuvem pode ser: - Entrega via internet de um serviço de Tecnologia da Informação, sob demanda, em um modelo de pague-pelo-que-consome. - Brown Field é quando você migra um serviço existente - - Green field é quando você começa do zero na nuvem, alguns também chamam isto de Cloud \ No newline at end of file + - Green field é quando você começa do zero na nuvem, alguns também chamam isto de Cloud + +## Ordered List +1. A + 1. B + 1. C + 1. D + 2. E + +## Mixed List +1. A + - B + 1. C + - D + - E + 2. F + 1. G + 2. H \ No newline at end of file From b912db0fd3251c28a09e905045d0c35a36220c1b Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Thu, 24 Mar 2022 22:21:30 -0400 Subject: [PATCH 104/477] Update CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index f133c924..57046141 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,6 +9,7 @@ - [pull #419] Fix hr block created when not supposed to (issue #400) - [pull #421] Fix backslashes removed by adjacent code blocks (issues #369 and #412) - [pull #420] Fix md5-* in resulting HTML when several code blocks follow one by one (issue #355) +- [pull #422] Fix excessive
    tags in lists using break-on-newline extra (issue #394) ## python-markdown2 2.4.2 From bd413d8fb1343350a78f7b5585d785efa7051a87 Mon Sep 17 00:00:00 2001 From: Crozzers Date: Mon, 28 Mar 2022 19:48:48 +0100 Subject: [PATCH 105/477] Standardize key and value definitions for metadata extra. (issue #423) Also split `_meta_data_pattern` regexp over multiple lines to improve readability. Metadata keys are now defined as `[\S \t]+\s*`, one or more non whitespace chars (or spaces/tabs) followed by an optional whitespace before the colon. Metadata values are defined as `.*`, zero or more non-newline characters. This change also fixes #398 --- lib/markdown2.py | 20 +++++++++++++------- test/tm-cases/metadata3.html | 1 + test/tm-cases/metadata3.metadata | 26 ++++++++++++++++++++++++++ test/tm-cases/metadata3.opts | 1 + test/tm-cases/metadata3.text | 32 ++++++++++++++++++++++++++++++++ 5 files changed, 73 insertions(+), 7 deletions(-) create mode 100644 test/tm-cases/metadata3.html create mode 100644 test/tm-cases/metadata3.metadata create mode 100644 test/tm-cases/metadata3.opts create mode 100644 test/tm-cases/metadata3.text diff --git a/lib/markdown2.py b/lib/markdown2.py index 500f5f68..f7076207 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -444,14 +444,20 @@ def preprocess(self, text): # another-var: blah blah # # # header - _meta_data_pattern = re.compile(r'^(?:---[\ \t]*\n)?((?:[\S\w]+\s*:(?:\n+[ \t]+.*)+)|(?:.*:\s+>\n\s+[\S\s]+?)(?=\n\w+\s*:\s*\w+\n|\Z)|(?:\s*[\S\w]+\s*:(?! >)[ \t]*.*\n?))(?:---[\ \t]*\n)?', re.MULTILINE) - _key_val_pat = re.compile(r"[\S\w]+\s*:(?! >)[ \t]*.*\n?", re.MULTILINE) - # this allows key: > - # value - # conutiues over multiple lines - _key_val_block_pat = re.compile( - r"(.*:\s+>\n\s+[\S\s]+?)(?=\n\w+\s*:\s*\w+\n|\Z)", re.MULTILINE + _meta_data_pattern = re.compile(r''' + ^(?:---[\ \t]*\n)?( # optional opening fence + (?: + [\S \t]+\s*:(?:\n+[ \t]+.*)+ # indented lists + )|(?: + (?:[\S \t]+\s*:\s+>(?:\n\s+.*)+?) # multiline long descriptions + (?=\n[\S \t]+\s*:\s*.*\n|\s*\Z) # match up until the start of the next key:value definition or the end of the input text + )|(?: + \s*[\S \t]+\s*:(?! >)[ \t]*.*\n? # simple key:value pair, leading spaces allowed + ) + )(?:---[\ \t]*\n)? # optional closing fence + ''', re.MULTILINE | re.VERBOSE ) + _key_val_list_pat = re.compile( r"^-(?:[ \t]*([^\n]*)(?:[ \t]*[:-][ \t]*(\S+))?)(?:\n((?:[ \t]+[^\n]+\n?)+))?", re.MULTILINE, diff --git a/test/tm-cases/metadata3.html b/test/tm-cases/metadata3.html new file mode 100644 index 00000000..2b85c958 --- /dev/null +++ b/test/tm-cases/metadata3.html @@ -0,0 +1 @@ +

    This tests various metadata key:value configurations to make sure they will work well consecutively

    diff --git a/test/tm-cases/metadata3.metadata b/test/tm-cases/metadata3.metadata new file mode 100644 index 00000000..f5033d0d --- /dev/null +++ b/test/tm-cases/metadata3.metadata @@ -0,0 +1,26 @@ +{ + "basic": "value", + "basic2": "test consecutive basic keys", + "empty": "", + "empty2": "", + "long-desc": "long multiline\n description\nwith varying levels of\n indentation", + "long-desc2": "test consecutive long descriptions", + "nested": [ + "list item", + "following a long description" + ], + "nested2": [ + "consecutive nested" + ], + "nested3": [ + { + "subkey": "with subkeys" + } + ], + "long-desc3": "long description following a nested", + "empty-following-long-desc": "", + "key with spaces": "will also be recognized", + "-key_start_with_hyphen": "allowed", + "tab indented key": "allowed", + "finish-with": "a nice long description\nover a couple lines" +} diff --git a/test/tm-cases/metadata3.opts b/test/tm-cases/metadata3.opts new file mode 100644 index 00000000..04e37532 --- /dev/null +++ b/test/tm-cases/metadata3.opts @@ -0,0 +1 @@ +{"extras": ["metadata"]} diff --git a/test/tm-cases/metadata3.text b/test/tm-cases/metadata3.text new file mode 100644 index 00000000..7dacdad1 --- /dev/null +++ b/test/tm-cases/metadata3.text @@ -0,0 +1,32 @@ +--- +basic: value +basic2: test consecutive basic keys +empty: +empty2 : +long-desc: > + long multiline + description + with varying levels of + indentation +long-desc2: > + test consecutive long descriptions +nested: + - list item + - following a long description +nested2: + - consecutive nested +nested3: + - + subkey: with subkeys +long-desc3: > + long description following a nested +empty-following-long-desc: +key with spaces: will also be recognized +-key_start_with_hyphen: allowed + tab indented key: allowed +finish-with : > + a nice long description + over a couple lines +--- + +This tests various metadata key:value configurations to make sure they will work well consecutively \ No newline at end of file From b956e9c9c92e91e1f064526d20dd8ee29615dc07 Mon Sep 17 00:00:00 2001 From: Crozzers Date: Thu, 7 Apr 2022 15:52:16 +0100 Subject: [PATCH 106/477] Remove redundant character class from `_meta_data_pattern` --- lib/markdown2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/markdown2.py b/lib/markdown2.py index f7076207..c8be9dc3 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -452,7 +452,7 @@ def preprocess(self, text): (?:[\S \t]+\s*:\s+>(?:\n\s+.*)+?) # multiline long descriptions (?=\n[\S \t]+\s*:\s*.*\n|\s*\Z) # match up until the start of the next key:value definition or the end of the input text )|(?: - \s*[\S \t]+\s*:(?! >)[ \t]*.*\n? # simple key:value pair, leading spaces allowed + \s*[\S \t]+\s*:(?! >).*\n? # simple key:value pair, leading spaces allowed ) )(?:---[\ \t]*\n)? # optional closing fence ''', re.MULTILINE | re.VERBOSE From 57ae040d7b635977f300da1a5dec617f3cfd6999 Mon Sep 17 00:00:00 2001 From: Crozzers Date: Thu, 7 Apr 2022 15:53:08 +0100 Subject: [PATCH 107/477] Fix metadata key definition to disallow pure whitespace keys. The previous definition, `[\S \t]+\s*` , would allow a completely whitespace key to exist. The new definition, `[\S \t]*\w[\S \t]*\s*` , allows keys that can contain spaces and tabs but requires at least one word character to be in the key somewhere --- lib/markdown2.py | 8 ++++---- test/tm-cases/metadata3.text | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/markdown2.py b/lib/markdown2.py index c8be9dc3..a0427d70 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -447,12 +447,12 @@ def preprocess(self, text): _meta_data_pattern = re.compile(r''' ^(?:---[\ \t]*\n)?( # optional opening fence (?: - [\S \t]+\s*:(?:\n+[ \t]+.*)+ # indented lists + [\S \t]*\w[\S \t]*\s*:(?:\n+[ \t]+.*)+ # indented lists )|(?: - (?:[\S \t]+\s*:\s+>(?:\n\s+.*)+?) # multiline long descriptions - (?=\n[\S \t]+\s*:\s*.*\n|\s*\Z) # match up until the start of the next key:value definition or the end of the input text + (?:[\S \t]*\w[\S \t]*\s*:\s+>(?:\n\s+.*)+?) # multiline long descriptions + (?=\n[\S \t]*\w[\S \t]*\s*:\s*.*\n|\s*\Z) # match up until the start of the next key:value definition or the end of the input text )|(?: - \s*[\S \t]+\s*:(?! >).*\n? # simple key:value pair, leading spaces allowed + [\S \t]*\w[\S \t]*\s*:(?! >).*\n? # simple key:value pair, leading spaces allowed ) )(?:---[\ \t]*\n)? # optional closing fence ''', re.MULTILINE | re.VERBOSE diff --git a/test/tm-cases/metadata3.text b/test/tm-cases/metadata3.text index 7dacdad1..e2e12687 100644 --- a/test/tm-cases/metadata3.text +++ b/test/tm-cases/metadata3.text @@ -1,4 +1,5 @@ --- + : empty key should be ignored basic: value basic2: test consecutive basic keys empty: From bdb1c16d985b28e60b64a1c7e7b935596e19b6f6 Mon Sep 17 00:00:00 2001 From: Crozzers Date: Thu, 7 Apr 2022 23:48:50 +0100 Subject: [PATCH 108/477] Don't test library against unsupported Python versions. Previously the tests would still be run against Python 2.7 if they found it installed on your machine. Now they will run on Python versions 3.5 to 3.10 and currently unreleased versions up to and including 3.19. --- test/testall.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/testall.py b/test/testall.py index 689fe5c0..b236cbbc 100644 --- a/test/testall.py +++ b/test/testall.py @@ -26,7 +26,8 @@ def _python_ver_from_python(python): def _gen_python_names(): yield "python" - for ver in [(2,6), (2,7), (3,3), (3,4), (3,5), (3,6), (3,7)]: + # generate version numbers from python 3.5 to 3.20 + for ver in [(3, i) for i in range(5, 20)]: yield "python%d.%d" % ver if sys.platform == "win32": yield "python%d%d" % ver @@ -43,8 +44,8 @@ def _gen_pythons(): def testall(): for ver, python in _gen_pythons(): - if ver < (2,6) or ver in ((3,0), (3,1), (3,2)): - # Don't support Python < 2.6, 3.0/3.1/3.2. + if ver < (3, 5): + # Don't support Python < 3.5 continue ver_str = "%s.%s" % ver print("-- test with Python %s (%s)" % (ver_str, python)) From b6aaa6874455ca2caa360696483ac915b5a8ff09 Mon Sep 17 00:00:00 2001 From: Crozzers Date: Fri, 8 Apr 2022 15:13:34 +0100 Subject: [PATCH 109/477] Remove mentions of Python2 support from readme --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index e1d44f5c..27425cda 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ was written to closely match the behaviour of the original Perl-implemented Markdown.pl. Markdown2 also comes with a number of extensions (called "extras") for things like syntax coloring, tables, header-ids. See the "Extra Syntax" section below. "markdown2" supports all Python versions -2.6+ or 3.3+ (and pypy and jython, though I don't frequently test those). +3.5+ (and pypy and jython, though I don't frequently test those). There is another [Python markdown.py](https://python-markdown.github.io/). However, at @@ -48,14 +48,14 @@ As a module: ```python >>> import markdown2 >>> markdown2.markdown("*boo!*") # or use `html = markdown_path(PATH)` -u'

    boo!

    \n' +'

    boo!

    \n' >>> from markdown2 import Markdown >>> markdowner = Markdown() >>> markdowner.convert("*boo!*") -u'

    boo!

    \n' +'

    boo!

    \n' >>> markdowner.convert("**boom!**") -u'

    boom!

    \n' +'

    boom!

    \n' ``` As a script (CLI): ```shell @@ -88,7 +88,7 @@ as a script: ```shell >>> import markdown2 >>> markdown2.markdown("*boo!*", extras=["footnotes"]) -u'

    boo!

    \n' +'

    boo!

    \n' ``` There are a number of currently implemented extras for tables, footnotes, syntax coloring of `
    `-blocks, auto-linking patterns, table of contents,
    
    From a16084d4f49dc19ac6f6437c92b9ac6adeb28585 Mon Sep 17 00:00:00 2001
    From: Crozzers 
    Date: Fri, 8 Apr 2022 19:09:35 +0100
    Subject: [PATCH 110/477] Fix #426
    
    The problem was that fenced code blocks would not be detected if placed inside a list (ul/ol) due to
    the leading indentation before the opening code fence.
    This commit tweaks the `_fenced_code_block_re` to ignore leading space/tab indents before an opening fence.
    
    `_code_block_sub` has also been altered to maintain the leading indentation when inserting code hashes as
    to not break the list (ul/ol) that the fenced code block is in.
    ---
     lib/markdown2.py                              | 11 +++++--
     .../tm-cases/fenced_code_blocks_issue426.html | 31 +++++++++++++++++++
     .../tm-cases/fenced_code_blocks_issue426.opts |  1 +
     .../tm-cases/fenced_code_blocks_issue426.tags |  1 +
     .../tm-cases/fenced_code_blocks_issue426.text | 26 ++++++++++++++++
     5 files changed, 68 insertions(+), 2 deletions(-)
     create mode 100644 test/tm-cases/fenced_code_blocks_issue426.html
     create mode 100644 test/tm-cases/fenced_code_blocks_issue426.opts
     create mode 100644 test/tm-cases/fenced_code_blocks_issue426.tags
     create mode 100644 test/tm-cases/fenced_code_blocks_issue426.text
    
    diff --git a/lib/markdown2.py b/lib/markdown2.py
    index beec36c9..4cff2215 100755
    --- a/lib/markdown2.py
    +++ b/lib/markdown2.py
    @@ -1879,10 +1879,17 @@ def unhash_code(codeblock):
                     return codeblock
                 lexer = self._get_pygments_lexer(lexer_name)
                 if lexer:
    +                # calculate code block's leading indent to not break lists
    +                leading_indent = re.match(r'[ \t]*(?=`{3,})', match.group(1))
    +                if leading_indent is not None:
    +                    leading_indent = leading_indent.group(0)
    +                else:
    +                    leading_indent = ''
    +
                     codeblock = unhash_code( codeblock )
                     colored = self._color_with_pygments(codeblock, lexer,
                                                         **formatter_opts)
    -                return "\n\n%s\n\n" % colored
    +                return "\n\n%s%s\n\n" % (leading_indent, colored)
     
             codeblock = self._encode_code(codeblock)
             pre_class_str = self._html_class_str_from_tag("pre")
    @@ -1930,7 +1937,7 @@ def _do_code_blocks(self, text):
     
         _fenced_code_block_re = re.compile(r'''
             (?:\n+|\A\n?|(?<=\n))
    -        (^`{3,})\s{0,99}?([\w+-]+)?\s{0,99}?\n  # $1 = opening fence (captured for back-referencing), $2 = optional lang
    +        (^[ \t]*`{3,})\s{0,99}?([\w+-]+)?\s{0,99}?\n  # $1 = opening fence (captured for back-referencing), $2 = optional lang
             (.*?)                             # $3 = code block content
             \1[ \t]*\n                      # closing fence
             ''', re.M | re.X | re.S)
    diff --git a/test/tm-cases/fenced_code_blocks_issue426.html b/test/tm-cases/fenced_code_blocks_issue426.html
    new file mode 100644
    index 00000000..4882d3d4
    --- /dev/null
    +++ b/test/tm-cases/fenced_code_blocks_issue426.html
    @@ -0,0 +1,31 @@
    +

    Django Templates

    + +

    NOTES

    + +
      +
    • The name should map to the URL.
    • +
    • No distro or app name prefix, they are namespaced by their dirs already
    • +
    • Since templates are made in python, the are named_with_underscores.html (not web style dashes).
    • +
    + +

    URL PARAMETERS IN THE TEMPLATE

    + +
      +
    • All views (except generic.View) from django.forms.generic inherit from ContextMixin
    • +
    • ContextMixin defines the method get_context_data:

      + +
          def get_context_data(self, **kwargs):
      +    kwargs.setdefault('view', self)
      +    if self.extra_context is not None:
      +        kwargs.update(self.extra_context)
      +    return kwargs
      +
      + +

      So when overriding one must be careful to extends super's kwargs:

      + +
          def get_context_data(self, **kwargs):
      +    kwargs = super().get_context_data(**kwargs)
      +    kwargs['page_title'] = "Documentation"
      +    return kwargs
      +
    • +
    diff --git a/test/tm-cases/fenced_code_blocks_issue426.opts b/test/tm-cases/fenced_code_blocks_issue426.opts new file mode 100644 index 00000000..20052b21 --- /dev/null +++ b/test/tm-cases/fenced_code_blocks_issue426.opts @@ -0,0 +1 @@ +{"extras": ["fenced-code-blocks", "pygments"]} diff --git a/test/tm-cases/fenced_code_blocks_issue426.tags b/test/tm-cases/fenced_code_blocks_issue426.tags new file mode 100644 index 00000000..2c03fb5d --- /dev/null +++ b/test/tm-cases/fenced_code_blocks_issue426.tags @@ -0,0 +1 @@ +extra fenced-code-blocks pygments diff --git a/test/tm-cases/fenced_code_blocks_issue426.text b/test/tm-cases/fenced_code_blocks_issue426.text new file mode 100644 index 00000000..b272c762 --- /dev/null +++ b/test/tm-cases/fenced_code_blocks_issue426.text @@ -0,0 +1,26 @@ +# Django Templates + +## NOTES + +- The name should map to the URL. +- No distro or app name prefix, they are namespaced by their dirs already +- Since templates are made in python, the are `named_with_underscores.html` (not web style dashes). + +## URL PARAMETERS IN THE TEMPLATE + +- All views (except `generic.View`) from `django.forms.generic` inherit from `ContextMixin` +- `ContextMixin` defines the method `get_context_data`: + ```python + def get_context_data(self, **kwargs): + kwargs.setdefault('view', self) + if self.extra_context is not None: + kwargs.update(self.extra_context) + return kwargs + ``` + So when overriding one must be careful to extends `super`'s `kwargs`: + ```py + def get_context_data(self, **kwargs): + kwargs = super().get_context_data(**kwargs) + kwargs['page_title'] = "Documentation" + return kwargs + ``` \ No newline at end of file From 9c1897b2bce1058932b5d2bb9accd1a1d01b7508 Mon Sep 17 00:00:00 2001 From: Nicholas Serra Date: Fri, 8 Apr 2022 15:21:15 -0400 Subject: [PATCH 111/477] Update CHANGES.md --- CHANGES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 57046141..6f4d996c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,6 +10,8 @@ - [pull #421] Fix backslashes removed by adjacent code blocks (issues #369 and #412) - [pull #420] Fix md5-* in resulting HTML when several code blocks follow one by one (issue #355) - [pull #422] Fix excessive
    tags in lists using break-on-newline extra (issue #394) +- [pull #424] Standardize key and value definitions for metadata extra (issue #423) +- [pull #427] Fix fenced code blocks breaking lists (issue #426) ## python-markdown2 2.4.2 From 96fab528d3b68cd80f78b712c314f957796f2d15 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Sat, 9 Apr 2022 18:07:18 +0200 Subject: [PATCH 112/477] fix catastrophic backtracking in pyshell code blocks --- CHANGES.md | 1 + lib/markdown2.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 6f4d996c..31f68c9b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,6 +12,7 @@ - [pull #422] Fix excessive
    tags in lists using break-on-newline extra (issue #394) - [pull #424] Standardize key and value definitions for metadata extra (issue #423) - [pull #427] Fix fenced code blocks breaking lists (issue #426) +- [pull #428] Fix catastrophic backtracking (Regex DoS) in pyshell blocks. ## python-markdown2 2.4.2 diff --git a/lib/markdown2.py b/lib/markdown2.py index aa74ab1b..0e886acb 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -1056,8 +1056,8 @@ def _prepare_pyshell_blocks(self, text): less_than_tab = self.tab_width - 1 _pyshell_block_re = re.compile(r""" - ^([ ]{0,%d})>>>[ ].*\n # first line - ^(\1.*\S+.*\n)* # any number of subsequent lines + ^([ ]{0,%d})>>>[ ].*\n # first line + ^(\1[^\S\n]*\S.*\n)* # any number of subsequent lines with at least one character ^\n # ends with a blank line """ % less_than_tab, re.M | re.X) From 7a3bc91ead2dae4c63c961e8f35e99c9788bbc2a Mon Sep 17 00:00:00 2001 From: Crozzers Date: Sat, 9 Apr 2022 11:39:58 +0100 Subject: [PATCH 113/477] Improve error message if `link_patterns` forgotten (#428) --- lib/markdown2.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/markdown2.py b/lib/markdown2.py index aa74ab1b..1d2966bf 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -2310,6 +2310,7 @@ def _encode_email_address(self, addr): return addr def _do_link_patterns(self, text): + assert self.link_patterns is not None, "If the 'link-patterns' extra is used, an argument for 'link_patterns' is required" link_from_hash = {} for regex, repl in self.link_patterns: replacements = [] From 2a543846cf37ead2eace4668af546fc4e10c0d5d Mon Sep 17 00:00:00 2001 From: Crozzers Date: Sun, 10 Apr 2022 16:41:33 +0100 Subject: [PATCH 114/477] Fix incorrect indentation of fenced code blocks within lists --- lib/markdown2.py | 24 +++++++++++++------ .../tm-cases/fenced_code_blocks_issue426.html | 4 ++-- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/lib/markdown2.py b/lib/markdown2.py index aa74ab1b..9f07155a 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -1885,17 +1885,27 @@ def unhash_code(codeblock): return codeblock lexer = self._get_pygments_lexer(lexer_name) if lexer: - # calculate code block's leading indent to not break lists - leading_indent = re.match(r'[ \t]*(?=`{3,})', match.group(1)) - if leading_indent is not None: - leading_indent = leading_indent.group(0) - else: - leading_indent = '' + def uniform_dedent(text): + # find leading indentation of each line + ws = re.findall(r'(^[ \t]*)(?:[^ \t\n])', text, re.MULTILINE) + # get smallest common leading indent + ws = sorted(ws)[0] + # dedent every line by smallest common indent + return ws, ''.join( + (line.replace(ws, '', 1) if line.startswith(ws) else line) + for line in text.splitlines(True) + ) + + # remove leading indent from code block + leading_indent, codeblock = uniform_dedent(codeblock) codeblock = unhash_code( codeblock ) colored = self._color_with_pygments(codeblock, lexer, **formatter_opts) - return "\n\n%s%s\n\n" % (leading_indent, colored) + + # add back the indent to all lines + colored = ''.join(leading_indent + line for line in colored.splitlines(True)) + return "\n\n%s\n\n" % colored codeblock = self._encode_code(codeblock) pre_class_str = self._html_class_str_from_tag("pre") diff --git a/test/tm-cases/fenced_code_blocks_issue426.html b/test/tm-cases/fenced_code_blocks_issue426.html index 4882d3d4..152711ba 100644 --- a/test/tm-cases/fenced_code_blocks_issue426.html +++ b/test/tm-cases/fenced_code_blocks_issue426.html @@ -14,7 +14,7 @@

    URL PARAMETERS IN THE TEMPLATE

  • All views (except generic.View) from django.forms.generic inherit from ContextMixin
  • ContextMixin defines the method get_context_data:

    -
        def get_context_data(self, **kwargs):
    +
    def get_context_data(self, **kwargs):
         kwargs.setdefault('view', self)
         if self.extra_context is not None:
             kwargs.update(self.extra_context)
    @@ -23,7 +23,7 @@ 

    URL PARAMETERS IN THE TEMPLATE

    So when overriding one must be careful to extends super's kwargs:

    -
        def get_context_data(self, **kwargs):
    +
    def get_context_data(self, **kwargs):
         kwargs = super().get_context_data(**kwargs)
         kwargs['page_title'] = "Documentation"
         return kwargs
    
    From 5898fcc1090ef7cd7783fa1422cc0e53cbca9d1b Mon Sep 17 00:00:00 2001
    From: Crozzers 
    Date: Sun, 10 Apr 2022 21:42:02 +0100
    Subject: [PATCH 115/477] Fix filter bypass leading to XSS (#362)
    
    ---
     lib/markdown2.py                 | 2 +-
     test/tm-cases/xss_issue_362.html | 2 ++
     test/tm-cases/xss_issue_362.opts | 1 +
     test/tm-cases/xss_issue_362.text | 2 ++
     4 files changed, 6 insertions(+), 1 deletion(-)
     create mode 100644 test/tm-cases/xss_issue_362.html
     create mode 100644 test/tm-cases/xss_issue_362.opts
     create mode 100644 test/tm-cases/xss_issue_362.text
    
    diff --git a/lib/markdown2.py b/lib/markdown2.py
    index aa74ab1b..750a50a0 100755
    --- a/lib/markdown2.py
    +++ b/lib/markdown2.py
    @@ -2249,7 +2249,7 @@ def _encode_amps_and_angles(self, text):
             text = self._naked_gt_re.sub('>', text)
             return text
     
    -    _incomplete_tags_re = re.compile(r"<(/?\w+?(?!\w).+?[\s/]+?)")
    +    _incomplete_tags_re = re.compile(r"<(/?\w+?(?!\w)\s*?.+?[\s/]+?)")
     
         def _encode_incomplete_tags(self, text):
             if self.safe_mode not in ("replace", "escape"):
    diff --git a/test/tm-cases/xss_issue_362.html b/test/tm-cases/xss_issue_362.html
    new file mode 100644
    index 00000000..9d878bd3
    --- /dev/null
    +++ b/test/tm-cases/xss_issue_362.html
    @@ -0,0 +1,2 @@
    +

    <iframe +onload=alert()//

    diff --git a/test/tm-cases/xss_issue_362.opts b/test/tm-cases/xss_issue_362.opts new file mode 100644 index 00000000..8d202ad0 --- /dev/null +++ b/test/tm-cases/xss_issue_362.opts @@ -0,0 +1 @@ +{"safe_mode": True} \ No newline at end of file diff --git a/test/tm-cases/xss_issue_362.text b/test/tm-cases/xss_issue_362.text new file mode 100644 index 00000000..3016199a --- /dev/null +++ b/test/tm-cases/xss_issue_362.text @@ -0,0 +1,2 @@ +