Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Toc nonstandard headers #337

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
1 change: 0 additions & 1 deletion .travis.yml
Expand Up @@ -2,7 +2,6 @@ language: python
python:
- "2.7"
- "pypy"
- "3.4"
- "3.5"
- "3.6"
- "3.7-dev"
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTORS.txt
Expand Up @@ -42,4 +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)
Ryan Vilbrandt (github.com/ryanvilbrandt)
18 changes: 10 additions & 8 deletions lib/markdown2.py
Expand Up @@ -1682,15 +1682,14 @@ def _do_lists(self, text):
(.*) # list item text = \2
''', re.M | re.X | re.S)

_task_list_warpper_str = r'<input type="checkbox" class="task-list-item-checkbox" %sdisabled> %s'
_task_list_warpper_str = r'<input type="checkbox" class="task-list-item-checkbox" %s%s> %s'

def _task_list_item_sub(self, match):
marker = match.group(1)
item_text = match.group(2)
if marker in ['[x]','[X]']:
return self._task_list_warpper_str % ('checked ', item_text)
elif marker == '[ ]':
return self._task_list_warpper_str % ('', item_text)
checked_str = "" if marker == '[ ]' else "checked "
disabled_str = "" if "task_list_checkable" in self.extras else "disabled"
return self._task_list_warpper_str % (checked_str, disabled_str, item_text)

_last_li_endswith_two_eols = False
def _list_item_sub(self, match):
Expand Down Expand Up @@ -2293,17 +2292,19 @@ def calculate_toc_html(toc):

This expects the `_toc` attribute to have been set on this instance.
"""
if toc is None:
if not toc:
return None

def indent():
return ' ' * (len(h_stack) - 1)
lines = []
h_stack = [0] # stack of header-level numbers
# Build TOC
for level, id, name in toc:
if level > h_stack[-1]:
lines.append("%s<ul>" % indent())
h_stack.append(level)
while level > h_stack[-1]:
lines.append("%s<ul>" % indent())
h_stack.append(h_stack[-1] + 1)
elif level == h_stack[-1]:
lines[-1] += "</li>"
else:
Expand All @@ -2314,6 +2315,7 @@ def indent():
lines.append("%s</ul></li>" % indent())
lines.append('%s<li><a href="#%s">%s</a>' % (
indent(), id, name))
# Added closing tags
while len(h_stack) > 1:
h_stack.pop()
if not lines[-1].endswith("</li>"):
Expand Down
4 changes: 2 additions & 2 deletions test/tm-cases/fenced_code_blocks_leading_lang_space.html
@@ -1,3 +1,3 @@
<div class="codehilite"><pre><span></span><code><span class="k">if</span> <span class="bp">True</span><span class="p">:</span>
<span class="k">print</span> <span class="s2">&quot;hi&quot;</span>
<div class="codehilite"><pre><span></span><code><span class="k">if</span> <span class="kc">True</span><span class="p">:</span>
<span class="nb">print</span> <span class="s2">&quot;hi&quot;</span>
</code></pre></div>
4 changes: 2 additions & 2 deletions test/tm-cases/fenced_code_blocks_safe_highlight.html
@@ -1,5 +1,5 @@
<div class="codehilite"><pre><span></span><code><span class="k">if</span> <span class="bp">True</span><span class="p">:</span>
<span class="k">print</span> <span class="s2">&quot;hi&quot;</span>
<div class="codehilite"><pre><span></span><code><span class="k">if</span> <span class="kc">True</span><span class="p">:</span>
<span class="nb">print</span> <span class="s2">&quot;hi&quot;</span>
</code></pre></div>

<p>That's using the <em>fenced-code-blocks</em> extra with Python
Expand Down
4 changes: 2 additions & 2 deletions test/tm-cases/fenced_code_blocks_syntax_highlighting.html
@@ -1,5 +1,5 @@
<div class="codehilite"><pre><span></span><code><span class="k">if</span> <span class="bp">True</span><span class="p">:</span>
<span class="k">print</span> <span class="s2">&quot;hi&quot;</span>
<div class="codehilite"><pre><span></span><code><span class="k">if</span> <span class="kc">True</span><span class="p">:</span>
<span class="nb">print</span> <span class="s2">&quot;hi&quot;</span>
</code></pre></div>

<p>That's using the <em>fenced-code-blocks</em> extra with Python
Expand Down
4 changes: 2 additions & 2 deletions test/tm-cases/fenced_code_blocks_syntax_indentation.html
@@ -1,5 +1,5 @@
<div class="codehilite"><pre><span></span><code><span class="k">def</span> <span class="nf">foo</span><span class="p">():</span>
<span class="k">print</span> <span class="s2">&quot;foo&quot;</span>
<span class="nb">print</span> <span class="s2">&quot;foo&quot;</span>

<span class="k">print</span> <span class="s2">&quot;bar&quot;</span>
<span class="nb">print</span> <span class="s2">&quot;bar&quot;</span>
</code></pre></div>
4 changes: 2 additions & 2 deletions test/tm-cases/issue3_bad_code_color_hack.html
Expand Up @@ -7,6 +7,6 @@ <h2>заголовок</h2>
<p>Some python code:</p>

<div class="codehilite"><pre><span></span><code><span class="c1"># комментарий</span>
<span class="k">if</span> <span class="bp">True</span><span class="p">:</span>
<span class="k">print</span> <span class="s2">&quot;hi&quot;</span>
<span class="k">if</span> <span class="kc">True</span><span class="p">:</span>
<span class="nb">print</span> <span class="s2">&quot;hi&quot;</span>
</code></pre></div>
6 changes: 4 additions & 2 deletions test/tm-cases/toc_2.toc_html
Expand Up @@ -6,8 +6,10 @@
<ul>
<li><a href="#beef">Beef</a>
<ul>
<li><a href="#steak">Steak</a></li>
<li><a href="#burgers">Burgers</a></li>
<ul>
<li><a href="#steak">Steak</a></li>
<li><a href="#burgers">Burgers</a></li>
</ul></li>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the orphaned li you mentioned? Is it present in master right now? Also wondering why we now have double nested ul in here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, that's the one. It probably doesn't exist in master right now, but I haven't taken a close look. I believe it's a side-effect of the change in this PR.

The double nested <ul> is the result of this PR. It allows for someone to place an <h5> after an <h3> and it indents twice in the TOC. This is happening in the toc_2 test case:

### Beef

##### Steak

##### Burgers

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay. I'll take a look at the code. Definitely not ideal to have the malformed html. The double ul doesn't seem necessary either, from a markup perspective. Seems the purpose of the PR should be able to be accomplished without an unnecessary ul. I'll dive in soon

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally, I think the nested <ul> is the right way to go. It seems odd, but it seems to follow good flow in the HTML where it relies on list level to determine indentation. It also means that markdown like this:

# Level 1

### Level 3

### Level 3

# Level 1

will be handled similarly to markdown like this:

# Level 1

## Level 2

### Level 3

### Level 3

# Level 1

I'll also mess around with the code a bit and see if I can reorganize the </li> tags to be a bit clearer.

</ul></li>
<li><a href="#chicken">Chicken</a></li>
<li><a href="#pork">Pork</a>
Expand Down
6 changes: 4 additions & 2 deletions test/tm-cases/toc_3.toc_html
Expand Up @@ -6,8 +6,10 @@
<ul>
<li><a href="#beef">Beef</a>
<ul>
<li><a href="#steak">Steak</a></li>
<li><a href="#burgers">Burgers</a></li>
<ul>
<li><a href="#steak">Steak</a></li>
<li><a href="#burgers">Burgers</a></li>
</ul></li>
</ul></li>
<li><a href="#chicken">Chicken</a></li>
<li><a href="#pork">Pork</a>
Expand Down
35 changes: 35 additions & 0 deletions test/tm-cases/toc_6.html
@@ -0,0 +1,35 @@
<p>Testing toc starting with a deeper header than h1</p>

<h3 id="fruit">Fruit</h3>

<ul>
<li>apples</li>
</ul>

<h2 id="veggies">Veggies</h2>

<ul>
<li>carrots</li>
</ul>

<p>Testing a jump in toc over more than two "layers"</p>

<h5 id="meat">Meat</h5>

<ul>
<li>beef</li>
</ul>

<h1 id="dairy">Dairy</h1>

<ul>
<li>milk</li>
</ul>

<p>Testing proper closing tags at end of toc</p>

<h3 id="sugar">Sugar</h3>

<ul>
<li>candy</li>
</ul>
1 change: 1 addition & 0 deletions test/tm-cases/toc_6.opts
@@ -0,0 +1 @@
{"extras": ["toc"]}
1 change: 1 addition & 0 deletions test/tm-cases/toc_6.tags
@@ -0,0 +1 @@
toc extra
25 changes: 25 additions & 0 deletions test/tm-cases/toc_6.text
@@ -0,0 +1,25 @@
Testing toc starting with a deeper header than h1

### Fruit

- apples

## Veggies

- carrots

Testing a jump in toc over more than two "layers"

##### Meat

- beef

# Dairy

- milk

Testing proper closing tags at end of toc

### Sugar

- candy
21 changes: 21 additions & 0 deletions test/tm-cases/toc_6.toc_html
@@ -0,0 +1,21 @@
<ul>
<ul>
<ul>
<li><a href="#fruit">Fruit</a></li>
</ul></li>
<li><a href="#veggies">Veggies</a>
<ul>
<ul>
<ul>
<li><a href="#meat">Meat</a></li>
</ul></li>
</ul></li>
</ul></li>
</ul></li>
<li><a href="#dairy">Dairy</a>
<ul>
<ul>
<li><a href="#sugar">Sugar</a></li>
</ul></li>
</ul></li>
</ul>