diff --git a/CHANGES.md b/CHANGES.md
index cee783ed..eca31d7d 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -26,6 +26,7 @@
- [pull #737] Fix XSS from code spans that the span gamut doesn't treat as code spans in safe mode (#726)
- [pull #743] Add a `strip-syntax` option to the `header-ids` extra that leaves link URLs, image paths, inline HTML tags and emphasis markers out of header ids (#192)
- [pull #747] Fix `link-patterns` extra linking text inside Markdown links and images whose label wraps onto another line
+- [pull #754] Fix `toc` extra generating invalid HTML when a header is higher than the first one, and nesting headers under the wrong parent after a skipped level
## python-markdown2 2.5.5
diff --git a/lib/markdown2.py b/lib/markdown2.py
index 3632a54e..75e25822 100755
--- a/lib/markdown2.py
+++ b/lib/markdown2.py
@@ -4639,11 +4639,18 @@ def indent():
elif level == h_stack[-1]:
lines[-1] += ""
else:
- while level < h_stack[-1]:
+ # Close nested lists until we're back in the one this header
+ # belongs in. The outermost list is never closed, so a header
+ # above the first one's level (eg: an h1 after an opening h2)
+ # stays at the top level.
+ while len(h_stack) > 2 and level <= h_stack[-2]:
h_stack.pop()
if not lines[-1].endswith(""):
lines[-1] += ""
lines.append("%s" % indent())
+ if not lines[-1].endswith(""):
+ lines[-1] += ""
+ h_stack[-1] = level
lines.append('{}
{}'.format(
indent(), id, name))
while len(h_stack) > 1:
diff --git a/test/tm-cases/toc_shallower_headers.html b/test/tm-cases/toc_shallower_headers.html
new file mode 100644
index 00000000..ce1eb311
--- /dev/null
+++ b/test/tm-cases/toc_shallower_headers.html
@@ -0,0 +1,15 @@
+Overview
+
+Getting Started
+
+Install
+
+Notes
+
+API
+
+Functions
+
+Classes
+
+Errors
diff --git a/test/tm-cases/toc_shallower_headers.opts b/test/tm-cases/toc_shallower_headers.opts
new file mode 100644
index 00000000..ac671854
--- /dev/null
+++ b/test/tm-cases/toc_shallower_headers.opts
@@ -0,0 +1 @@
+{"extras": ["toc"]}
diff --git a/test/tm-cases/toc_shallower_headers.tags b/test/tm-cases/toc_shallower_headers.tags
new file mode 100644
index 00000000..2b2472e0
--- /dev/null
+++ b/test/tm-cases/toc_shallower_headers.tags
@@ -0,0 +1 @@
+toc extra
diff --git a/test/tm-cases/toc_shallower_headers.text b/test/tm-cases/toc_shallower_headers.text
new file mode 100644
index 00000000..8017b2b3
--- /dev/null
+++ b/test/tm-cases/toc_shallower_headers.text
@@ -0,0 +1,15 @@
+## Overview
+
+# Getting Started
+
+## Install
+
+### Notes
+
+# API
+
+### Functions
+
+## Classes
+
+## Errors
diff --git a/test/tm-cases/toc_shallower_headers.toc_html b/test/tm-cases/toc_shallower_headers.toc_html
new file mode 100644
index 00000000..9883cc71
--- /dev/null
+++ b/test/tm-cases/toc_shallower_headers.toc_html
@@ -0,0 +1,16 @@
+