Skip to content

HTML <table> elements rendered as flat concatenated text instead of markdown table #38

Description

@ClementRmc

Bug: HTML <table> elements rendered as flat concatenated text instead of markdown table

Summary

When a WordPress post contains an HTML <table> (built with Gutenberg, Classic Editor, or any page builder), the markdown output collapses every cell value into a single unstructured text block. All semantic structure is lost — column headers, row boundaries, and cell separation disappear.

This makes the markdown output significantly less useful for the plugin's primary use cases (LLM ingestion, agent retrieval), since tabular data is one of the most information-dense content patterns publishers expose.

Steps to reproduce

  1. Create a WordPress post containing a standard HTML table (for instance a pricing or comparison table).
  2. Request the .md version of the post (or use Accept: text/markdown content negotiation).
  3. Observe how the table is rendered in the markdown output.

Example

HTML input

<table>
  <thead>
    <tr>
      <th>Plan</th>
      <th>Price</th>
      <th>Storage</th>
      <th>Support</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Free</td>
      <td>$0</td>
      <td>5 GB</td>
      <td>Community</td>
    </tr>
    <tr>
      <td>Pro</td>
      <td>$10/mo</td>
      <td>100 GB</td>
      <td>Email</td>
    </tr>
    <tr>
      <td>Enterprise</td>
      <td>Custom</td>
      <td>Unlimited</td>
      <td>Dedicated</td>
    </tr>
  </tbody>
</table>

Current output

PlanPriceStorageSupportFree$05 GBCommunityPro$10/mo100 GBEmailEnterpriseCustomUnlimitedDedicated

All structure is lost. A consumer cannot recover the original 4-column × 3-row table from this output.

Expected output (GitHub Flavored Markdown table syntax)

| Plan       | Price   | Storage   | Support   |
| ---------- | ------- | --------- | --------- |
| Free       | $0      | 5 GB      | Community |
| Pro        | $10/mo  | 100 GB    | Email     |
| Enterprise | Custom  | Unlimited | Dedicated |

Root cause

The underlying converter league/html-to-markdown does not ship with a <table> converter out of the box. When no converter handles a tag, its inline text is collected without separators, producing the concatenated output observed above. This is a known limitation of the library.

Suggested fix

Two viable approaches:

Option A — Custom Converter (recommended). Implement a TableConverter class in src/Converter/ that implements League\HTMLToMarkdown\Converter\ConverterInterface, returns ['table', 'thead', 'tbody', 'tr', 'th', 'td'] from getSupportedTags(), and emits GFM pipe-table syntax. Register it on the HtmlConverter instance in MarkdownConverter::__construct() via $this->converter->getEnvironment()->addConverter(new TableConverter()).

Option B — HTML pre-processing. Pre-walk the HTML with DOMDocument in MarkdownConverter::convert() before calling $this->converter->convert($html). Replace each <table> node with its pre-computed markdown equivalent wrapped in a placeholder, then unwrap after conversion.

Option A is cleaner because it integrates with the library's extension model and handles nested cases (links, formatting, lists inside cells) via the existing converter chain.

Environment

  • Markdown Alternate version: 1.1.0
  • WordPress version: 6.7
  • PHP version: 8.2
  • Page builder used in the test post: Gutenberg

Why this matters

Markdown Alternate's value proposition is "clean structured content for LLMs and agents". Tables encode exactly the kind of dense, comparative information that benefits most from markdown ingestion (specs, comparisons, schedules, pricing). Losing them silently is a meaningful regression versus simply scraping the HTML.

Happy to test a patch once available.

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions