What a Markdown stripper throws away, and how to keep it
“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 URL behind a link
[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.