Skip to content

Commit c13bdd5

Browse files
committed
Fix logic for indentation inside list items
This fixes problems with the markdownify logic for indentation inside list items. This PR uses a branch building on that for #120, #150 and #151, so those three PRs should be merged first before merging this one. There is limited logic in markdownify for handling indentation in the case of nested lists. There are two major problems with this logic: * As it's in `convert_list`, causing a list to be indented when inside another list, it does not add indentation for any other elements such as paragraphs that may be found inside list items (or `<pre>`, `<blockquote>`, etc.), so such elements are wrongly not indented and terminate the list in the output. * It uses fixed indentation of one tab. Following CommonMark, a tab in Markdown is considered equivalent to four spaces, which is not sufficient indentation in ordered list items with a number of three or more digits. Fix both of these issues by making `convert_li` handle indentation for the contents of `<li>`, based on the length of the list item marker, rather than doing it in `convert_list` at all.
1 parent 340aecb commit c13bdd5

File tree

2 files changed

+14
-7
lines changed

2 files changed

+14
-7
lines changed

markdownify/__init__.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,8 @@ def escape(self, text):
244244
text = text.replace('_', r'\_')
245245
return text
246246

247-
def indent(self, text, level):
248-
return line_beginning_re.sub('\t' * level, text) if text else ''
247+
def indent(self, text, columns):
248+
return line_beginning_re.sub(' ' * columns, text) if text else ''
249249

250250
def underline(self, text, pad_char):
251251
text = (text or '').rstrip()
@@ -346,7 +346,7 @@ def convert_list(self, el, text, convert_as_inline):
346346
el = el.parent
347347
if nested:
348348
# remove trailing newline if nested
349-
return '\n' + self.indent(text, 1).rstrip()
349+
return '\n' + text.rstrip()
350350
return '\n\n' + text + ('\n' if before_paragraph else '')
351351

352352
convert_ul = convert_list
@@ -368,7 +368,12 @@ def convert_li(self, el, text, convert_as_inline):
368368
el = el.parent
369369
bullets = self.options['bullets']
370370
bullet = bullets[depth % len(bullets)]
371-
return '%s %s\n' % (bullet, (text or '').strip())
371+
bullet = bullet + ' '
372+
text = (text or '').strip()
373+
text = self.indent(text, len(bullet))
374+
if text:
375+
text = bullet + text[len(bullet):]
376+
return '%s\n' % text
372377

373378
def convert_p(self, el, text, convert_as_inline):
374379
if convert_as_inline:

tests/test_lists.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,11 @@ def test_ol():
4747
assert md('<ol start="-1"><li>a</li><li>b</li></ol>') == '\n\n1. a\n2. b\n'
4848
assert md('<ol start="foo"><li>a</li><li>b</li></ol>') == '\n\n1. a\n2. b\n'
4949
assert md('<ol start="1.5"><li>a</li><li>b</li></ol>') == '\n\n1. a\n2. b\n'
50+
assert md('<ol start="1234"><li><p>first para</p><p>second para</p></li><li><p>third para</p><p>fourth para</p></li></ol>') == '\n\n1234. first para\n \n second para\n1235. third para\n \n fourth para\n'
5051

5152

5253
def test_nested_ols():
53-
assert md(nested_ols) == '\n\n1. 1\n\t1. a\n\t\t1. I\n\t\t2. II\n\t\t3. III\n\t2. b\n\t3. c\n2. 2\n3. 3\n'
54+
assert md(nested_ols) == '\n\n1. 1\n 1. a\n 1. I\n 2. II\n 3. III\n 2. b\n 3. c\n2. 2\n3. 3\n'
5455

5556

5657
def test_ul():
@@ -63,6 +64,7 @@ def test_ul():
6364
<li> c
6465
</li>
6566
</ul>""") == '\n\n* a\n* b\n* c\n'
67+
assert md('<ul><li><p>first para</p><p>second para</p></li><li><p>third para</p><p>fourth para</p></li></ul>') == '\n\n* first para\n \n second para\n* third para\n \n fourth para\n'
6668

6769

6870
def test_inline_ul():
@@ -75,11 +77,11 @@ def test_nested_uls():
7577
Nested ULs should alternate bullet characters.
7678
7779
"""
78-
assert md(nested_uls) == '\n\n* 1\n\t+ a\n\t\t- I\n\t\t- II\n\t\t- III\n\t+ b\n\t+ c\n* 2\n* 3\n'
80+
assert md(nested_uls) == '\n\n* 1\n + a\n - I\n - II\n - III\n + b\n + c\n* 2\n* 3\n'
7981

8082

8183
def test_bullets():
82-
assert md(nested_uls, bullets='-') == '\n\n- 1\n\t- a\n\t\t- I\n\t\t- II\n\t\t- III\n\t- b\n\t- c\n- 2\n- 3\n'
84+
assert md(nested_uls, bullets='-') == '\n\n- 1\n - a\n - I\n - II\n - III\n - b\n - c\n- 2\n- 3\n'
8385

8486

8587
def test_li_text():

0 commit comments

Comments
 (0)