Markdown conversion: HTML, tables and what is lossy

Converting to Markdown is a reduction, not a reformat. Knowing which structures have an equivalent — and which are silently flattened — is what stops a clean-looking output from losing meaning.

Two directions, two different jobs

HTML → Markdown is for moving content out of a CMS, a web page or an email into a README, a wiki or a docs repository. Markdown → HTML is for rendering that source back into a page. They are not inverses: the first throws away everything Markdown cannot express, and the second only understands the subset it implements. A round trip is lossy in the middle, and that is a property of the formats, not a bug in a converter.

What the conversion produces, measured

The table below is output from the same functions the pages run, on small inputs. It shows the shapes that matter: headings, emphasis, links, ordered lists and a GFM table.

InputOutput
<h1>Title</h1><p>A <strong>bold</strong> <a href="/x">link</a>.</p># Title then A **bold** [link](/x).
<ol><li>one</li><li>two</li></ol>1. one / 2. two
Header Name, Age; rows Ann, 30 and Bob, 5| Name | Age | with | :--- | ---: | when the columns are left and right aligned

The table row is the output of the Markdown table generator with per-column alignment; the first two are the HTML converter. Note that the ordered list keeps its numbers — an earlier version emitted bullets and silently turned a sequence into a set.

What is lost

  • Presentation. Classes, inline styles, colours and fonts have no Markdown equivalent and are dropped. That is the point of the conversion.
  • Nested lists. An inner list inside a list item is flattened into the parent's text by a tag-based converter. Two-level menus and outlines need their indentation restored by hand; a converter that walks a DOM tree can preserve it, but this page's engine prioritises predictable output over full nesting.
  • Tables with merged cells. A Markdown table has no rowspan or colspan. Cells that were merged simply do not exist in the output, so the grid can look complete while missing information.
  • Semantics without syntax. Definition lists, figures and captions, collapsible sections and form controls reduce to their text. The words survive; the meaning of the element does not.
  • Raw HTML. Inline <span>, <sup> and custom elements are stripped to text. If you need them preserved, a Markdown converter is the wrong tool.

Tables are a grammar, not a layout

A GFM table is a header row, a delimiter row that sets alignment, and data rows separated by pipes. The delimiter row is what tells the renderer how each column aligns: :--- left, :---: centre, ---: right. A literal pipe inside a cell must be written as \| or the row splits in the wrong place. The table generator does that escaping, which is the main reason to use it rather than typing the syntax by hand.

Two limits are worth remembering. A blank line ends the table, so a table cannot contain an empty row partway through. And a table is only as wide as its header: a data row with more cells than the header loses the extras rather than growing an unnamed column. The generator pads short rows and truncates long ones, which keeps the output valid but means you should check the header first if columns go missing.

Line breaks and hard wraps

Markdown treats a single newline as a space; a hard break needs two trailing spaces or a backslash at the end of the line. A converter that turns <br> into a plain newline therefore produces a break that most renderers show as a space. If the break matters — an address, a poem, a signature — add the two spaces or use a list, and check the rendered result rather than the source. This is also why pasting PDF prose into Markdown and then rendering it can reflow every line.

Choosing the tool

You haveYou wantUse
HTML from a CMS or a pageMarkdown for a README or docsHTML to Markdown
Markdown sourceHTML to paste into a pageMarkdown to HTML
Spreadsheet rows or typed dataA Markdown tableMarkdown table generator
An array of JSON objectsA table in HTML, Markdown, CSV or SQLJSON to table

For prose that must keep its formatting, keep the HTML. Markdown is a source format for content that is meant to be edited by hand and rendered by many tools; it is not a lossless archive of a styled document.

Questions this guide raises

Why did my nested list lose its indentation?

A tag-based converter matches list items and flattens the inner list into the parent item. Markdown itself supports nesting with indentation, but producing it correctly requires walking the tree and tracking depth; the page’s converter keeps the output predictable instead. Restore the indentation by hand for outlines and menus.

Can I convert a table with merged cells?

Not losslessly. Markdown has no rowspan or colspan, so merged cells have no representation. The converter emits the grid it can represent; the merged content is either repeated or lost depending on the source. For a table that depends on merging, keep an HTML copy or use a format that supports it.

Is the HTML produced by Markdown to HTML safe to paste?

It is a rendering of the Markdown subset, not a sanitiser. If the source includes raw HTML or a link with a javascript: URL, that is what the output contains. Treat rendered Markdown from an untrusted author like any other untrusted HTML, and sanitise it before inserting it into a page.