Skip to content
PlainPaste

Blog

What a Markdown stripper throws away, and how to keep it

markdownplain textdesign decisions

“Strip the Markdown” sounds like one operation. It is really a series of small decisions, and a converter makes every one of them for you whether it admits to it or not.

Here is what usually gets decided badly.

List numbering

The most consequential one. The common libraries treat a list as a formatting construct and flatten it, which removes 1. 2. 3. along with the bullet characters.

For a bulleted list that is arguably fine. For a numbered one it destroys the meaning: the numbers were referring to something. Answers to a numbered questionnaire, steps in a sequence, ranked items — all become an unordered pile.

Numbering is kept here, including lists that start at 7, and including a numbered list nested inside another one.

[the docs](https://example.com/guide) has two pieces of information. Plain text has nowhere to put the second one, so a converter must either write it out or drop it.

Dropping it is silent and common. The reader gets “the docs” and no way to reach them. The default here writes both — the docs (https://example.com/guide) — because a reader who cannot follow the link has lost something. Text-only and URL-only are available when you know the link does not matter.

The language of a code block

A fence marked ```java carries a fact: this is Java. Strip the fence and that fact goes with it, leaving a block of unexplained symbols that could be anything.

The language is emitted as a label — [java] — so a reader can tell. Off, or kept as the original fence, if you prefer.

Image alt text

An image cannot survive as an image. But its alt text is a sentence someone wrote to describe it, and it is often the only description of that content in the document. Discarding the image and keeping the description is usually better than discarding both.

Footnotes, quotes, dividers, frontmatter

Each is content that a stripper may quietly remove. Each is kept by default here and individually switchable.

Why lossless is the right default

The test that settles most of these: could a reader who never saw the input understand everything it said, from the output alone?

If the answer is no, the converter has thrown information away on the reader’s behalf without asking. A converter that leaves something you have to delete yourself is annoying for ten seconds. One that deletes something you needed is a problem you may not notice until it matters.

So the defaults keep everything, and every removal is a switch you choose. One preset — Report & tables — deliberately breaks that rule and strips code blocks and images, because it exists to lift a comparison table into a report where a stray snippet is noise. It is the exception, it says so, and the Default preset strips nothing at all.

The things that genuinely have no answer

Some decisions have no correct default, only a context:

  • What does a heading look like with no way to be a heading? Plain, uppercase, or # kept.
  • What does a table look like with no table? Aligned columns, tabs, or label-and-value.
  • What does a task list look like? [ ], , or nothing.

These are why the presets exist. Rather than pick one and call it universal, each preset answers all of them for a particular destination — an email client, a spreadsheet, a chat window, a documentation page, a web form — and shows you a sample so you can see the answers before you trust them.

Try the converter →