Repository: matthewwithanm/python-markdownify
Pull request #63 (2022-03-23 08:58:30)

Fix detection of "first row, not headline"
For me, this fixes the conversion of HTML tables without a header.


AlexVonB: Hi! Unfortunately, this breaks some tests. Also, we check for tables without heads and handle them correctly:

https://github.com/matthewwithanm/python-markdownify/blob/b589863715918dca3c8bd3f3ffa0d0b06245bd30/tests/test_tables.py#L124-L140

This is converted to
https://github.com/matthewwithanm/python-markdownify/blob/b589863715918dca3c8bd3f3ffa0d0b06245bd30/tests/test_tables.py#L150

Could you please provide some example? Thanks!
AlexVonB: Great, thank you! I'll merge this tomorrow to wait for possible last fixes :D Best!
mvkorpel: Hi @AlexVonB ! My original fix was clearly a sloppy one, as it only addressed a particular case I had: a table with a `<tbody>` but no `<thead>`. Unfortunately, the "fix" broke some other cases which probably were not present in my test input, and I was regrettably too lazy to have run your test suite. The updated pull request should be better. Apologies.

I'm sorry that the commit history now looks a bit dirty.
AlexVonB: No problem at all! We did not have a test case for just a `tbody`, so your PR is great to improve resiliency! The commits will be squashed on merge, so no worries there. Thanks again!

Patch:
diff --git a/markdownify/__init__.py b/markdownify/__init__.py
index d6d36a0..8461c1c 100644
--- a/markdownify/__init__.py
+++ b/markdownify/__init__.py
@@ -370,8 +370,13 @@ class MarkdownConverter(object):
         if is_headrow and not el.previous_sibling:
             # first row and is headline: print headline underline
             underline += '| ' + ' | '.join(['---'] * len(cells)) + ' |' + '\n'
-        elif not el.previous_sibling and not el.parent.name != 'table':
-            # first row, not headline, and the parent is sth. like tbody:
+        elif (not el.previous_sibling
+              and (el.parent.name == 'table'
+                   or (el.parent.name == 'tbody'
+                       and not el.parent.previous_sibling))):
+            # first row, not headline, and:
+            # - the parent is table or
+            # - the parent is tbody at the beginning of a table.
             # print empty headline above this row
             overline += '| ' + ' | '.join([''] * len(cells)) + ' |' + '\n'
             overline += '| ' + ' | '.join(['---'] * len(cells)) + ' |' + '\n'


Test patch:
diff --git a/tests/test_tables.py b/tests/test_tables.py
index 27d4403..e0c07ea 100644
--- a/tests/test_tables.py
+++ b/tests/test_tables.py
@@ -139,6 +139,26 @@ table_missing_head = """<table>
     </tr>
 </table>"""
 
+table_body = """<table>
+    <tbody>
+        <tr>
+            <td>Firstname</td>
+            <td>Lastname</td>
+            <td>Age</td>
+        </tr>
+        <tr>
+            <td>Jill</td>
+            <td>Smith</td>
+            <td>50</td>
+        </tr>
+        <tr>
+            <td>Eve</td>
+            <td>Jackson</td>
+            <td>94</td>
+        </tr>
+    </tbody>
+</table>"""
+
 
 def test_table():
     assert md(table) == '\n\n| Firstname | Lastname | Age |\n| --- | --- | --- |\n| Jill | Smith | 50 |\n| Eve | Jackson | 94 |\n\n'
@@ -148,3 +168,4 @@ def test_table():
     assert md(table_head_body) == '\n\n| Firstname | Lastname | Age |\n| --- | --- | --- |\n| Jill | Smith | 50 |\n| Eve | Jackson | 94 |\n\n'
     assert md(table_missing_text) == '\n\n|  | Lastname | Age |\n| --- | --- | --- |\n| Jill |  | 50 |\n| Eve | Jackson | 94 |\n\n'
     assert md(table_missing_head) == '\n\n|  |  |  |\n| --- | --- | --- |\n| Firstname | Lastname | Age |\n| Jill | Smith | 50 |\n| Eve | Jackson | 94 |\n\n'
+    assert md(table_body) == '\n\n|  |  |  |\n| --- | --- | --- |\n| Firstname | Lastname | Age |\n| Jill | Smith | 50 |\n| Eve | Jackson | 94 |\n\n'