[BUG] `htmlToMarkdown()` crashes on tables with no rows

htmlToMarkdown() crashes on some valid HTML markup.

Failing examples

import { htmlToMarkdown } from 'obsidian';

// Crash: empty table
htmlToMarkdown('<table></table>')

// Crash: table with empty tbody only
htmlToMarkdown('<table><tbody></tbody></table>')

// Crash: table with empty thead only
htmlToMarkdown('<table><thead></thead></table>')

// Crash: table with whitespace but no <tr>
htmlToMarkdown('<table><tbody>  </tbody></table>')

// Crash: table with nested divs but no <tr>
htmlToMarkdown('<table><tbody><div>text</div></tbody></table>')

all of them are failing with

Uncaught TypeError: Cannot read properties of undefined (reading 'cells')
    at Object.replacement (app.js:1:1535239)
    at k.D (turndown.js:2:9605)
    at turndown.js:2:9264
    at NodeList.reduce (<anonymous>)
    at k.b (turndown.js:2:9113)
    at k.turndown (turndown.js:2:10124)
    at Module.yP (app.js:1:1533581)
    at <anonymous>:1:20

Semi-working examples

If the table has some rows, even semantically incorrect HTML is still parsed. Not to real markdown tables, but at least, it doesn’t crash.

htmlToMarkdown('<table><tbody></tbody><tbody><tr><td>x</td></tr></tbody></table>');

Root cause

The bundled turndown GFM tables plugin accesses node.rows[0].cells without checking that node.rows[0] exists. Any <table> element with zero <tr> descendants triggers this.

Real-world impact

Discovered in https://github.com/mnaoumov/obsidian-email-to-vault/issues/3 when trying to use htmlToMarkdown() to convert email HTML to markdown. Email HTML commonly uses layout tables (role="presentation") with empty elements.

Workaround

Strip empty table sections from HTML before passing to htmlToMarkdown():

const doc = new DOMParser().parseFromString(html, 'text/html');
for (const table of doc.querySelectorAll('table')) {
  if (!table.querySelector('tr')) {
      table.remove();
  }
}

htmlToMarkdown(doc.body.innerHTML);

Environment

SYSTEM INFO:
	Obsidian version: 1.12.7
	Installer version: 1.12.7
	Operating system: Windows 11 Pro 10.0.26200
	Login status: logged in
	Language: en
	Catalyst license: vip
	Insider build toggle: on
	Live preview: on
	Base theme: adapt to system
	Community theme: none
	Snippets enabled: 0
	Restricted mode: off
	Plugins installed: 0
	Plugins enabled: 0

RECOMMENDATIONS:
	none

thanks