Repository: matthewwithanm/python-markdownify

Issue:
ordered list issue
Hello :)

I encountered a probleme markdownifying ordered lists:

given `html = '<ol>\n<li>a</li>\n<li>b</li>\n<li>c</li>\n</ol>'`

the ol node list is: `['\n', <li>w</li>, '\n', <li>t</li>, '\n', <li>f</li>, '\n']`

as `bullet = '%s.' % (parent.index(el) + 1)`,

the result is:

```
: markdownify(html)
: ' 2. a\n 4. b\n 6. c\n '
```
<=>
```
 2. a
 4. b
 6. c
```

I could preprocess my html input before passing it to markdonify but I'm affraid to loose "meaningfull linebreaks" if such things even exist ^^
I think this might be handled in the library, what do you think?

Thank you !

Discussion:

Patch:
diff --git a/markdownify/__init__.py b/markdownify/__init__.py
index eeaaf74..da04ebf 100644
--- a/markdownify/__init__.py
+++ b/markdownify/__init__.py
@@ -6,6 +6,7 @@ import six
 convert_heading_re = re.compile(r'convert_h(\d+)')
 line_beginning_re = re.compile(r'^', re.MULTILINE)
 whitespace_re = re.compile(r'[\t ]+')
+all_whitespace_re = re.compile(r'[\s]+')
 html_heading_re = re.compile(r'h[1-6]')
 
 
@@ -83,12 +84,18 @@ class MarkdownConverter(object):
         if not children_only and isHeading:
             convert_children_as_inline = True
 
+        # Remove whitespace-only textnodes in lists
+        if node.name in ['ol', 'ul', 'li']:
+            for el in node.children:
+                if isinstance(el, NavigableString) and six.text_type(el).strip() == '':
+                    el.extract()
+
         # Convert the children first
         for el in node.children:
             if isinstance(el, Comment):
                 continue
             elif isinstance(el, NavigableString):
-                text += self.process_text(six.text_type(el))
+                text += self.process_text(el)
             else:
                 text += self.process_tag(el, convert_children_as_inline)
 
@@ -99,7 +106,10 @@ class MarkdownConverter(object):
 
         return text
 
-    def process_text(self, text):
+    def process_text(self, el):
+        text = six.text_type(el)
+        if el.parent.name == 'li':
+            return escape(all_whitespace_re.sub(' ', text or '')).rstrip()
         return escape(whitespace_re.sub(' ', text or ''))
 
     def __getattr__(self, attr):
@@ -199,6 +209,9 @@ class MarkdownConverter(object):
         # Ignoring convert_to_inline for list.
 
         nested = False
+        before_paragraph = False
+        if el.next_sibling and el.next_sibling.name not in ['ul', 'ol']:
+            before_paragraph = True
         while el:
             if el.name == 'li':
                 nested = True
@@ -207,7 +220,7 @@ class MarkdownConverter(object):
         if nested:
             # remove trailing newline if nested
             return '\n' + self.indent(text, 1).rstrip()
-        return '\n' + text + '\n'
+        return text + ('\n' if before_paragraph else '')
 
     convert_ul = convert_list
     convert_ol = convert_list


Test patch:
diff --git a/tests/test_conversions.py b/tests/test_conversions.py
index 9d25940..caac0fd 100644
--- a/tests/test_conversions.py
+++ b/tests/test_conversions.py
@@ -2,7 +2,7 @@ from markdownify import markdownify as md, ATX, ATX_CLOSED, BACKSLASH, UNDERSCOR
 import re
 
 
-nested_uls = re.sub(r'\s+', '', """
+nested_uls = """
     <ul>
         <li>1
             <ul>
@@ -19,7 +19,26 @@ nested_uls = re.sub(r'\s+', '', """
         </li>
         <li>2</li>
         <li>3</li>
-    </ul>""")
+    </ul>"""
+
+nested_ols = """
+    <ol>
+        <li>1
+            <ol>
+                <li>a
+                    <ol>
+                        <li>I</li>
+                        <li>II</li>
+                        <li>III</li>
+                    </ol>
+                </li>
+                <li>b</li>
+                <li>c</li>
+            </ol>
+        </li>
+        <li>2</li>
+        <li>3</li>
+    </ul>"""
 
 
 table = re.sub(r'\s+', '', """
@@ -253,8 +272,8 @@ def test_i():
 
 
 def test_ol():
-    assert md('<ol><li>a</li><li>b</li></ol>') == '\n1. a\n2. b\n\n'
-    assert md('<ol start="3"><li>a</li><li>b</li></ol>') == '\n3. a\n4. b\n\n'
+    assert md('<ol><li>a</li><li>b</li></ol>') == '1. a\n2. b\n'
+    assert md('<ol start="3"><li>a</li><li>b</li></ol>') == '3. a\n4. b\n'
 
 
 def test_p():
@@ -266,11 +285,15 @@ def test_strong():
 
 
 def test_ul():
-    assert md('<ul><li>a</li><li>b</li></ul>') == '\n* a\n* b\n\n'
+    assert md('<ul><li>a</li><li>b</li></ul>') == '* a\n* b\n'
+
+
+def test_nested_ols():
+    assert md(nested_ols) == '\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'
 
 
 def test_inline_ul():
-    assert md('<p>foo</p><ul><li>a</li><li>b</li></ul><p>bar</p>') == 'foo\n\n\n* a\n* b\n\nbar\n\n'
+    assert md('<p>foo</p><ul><li>a</li><li>b</li></ul><p>bar</p>') == 'foo\n\n* a\n* b\n\nbar\n\n'
 
 
 def test_nested_uls():
@@ -278,11 +301,11 @@ def test_nested_uls():
     Nested ULs should alternate bullet characters.
 
     """
-    assert md(nested_uls) == '\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\n'
+    assert md(nested_uls) == '\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'
 
 
 def test_bullets():
-    assert md(nested_uls, bullets='-') == '\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\n'
+    assert md(nested_uls, bullets='-') == '\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'
 
 
 def test_img():