Markdown to Plain Text Converter That Lets You Choose What Survives
This markdown to plain text converter gives you back your document with your own decisions about links, code fences, tables and list markers, rather than the defaults somebody else picked.
Short version
Three settings decide almost everything: whether links keep their URL, how a table is flattened, and whether fenced code is kept. Pick a destination preset in the tool below and all three are set for you, or read the destination table for the reasoning behind each one.
Markdown to plain text converter
The document is parsed rather than pattern matched, so a hash inside a code fence stays a hash. Conversion happens in this tab and nothing is uploaded.
Where are you pasting this
Pick one to set every option below at once, or leave it and choose them yourself.
0 characters out of 0 in
Try a document shape and change a setting
Which settings suit where you are pasting
| Pasting into | Links | Tables | Why |
|---|---|---|---|
| Email body | Words and URL | One line per cell | A reader cannot click a link that lost its address, and mail clients rewrap padded columns into nonsense. |
| ATS or job application form | Words only | Comma separated | Character limits are tight and a raw URL burns forty of them. Nested indentation often gets collapsed anyway. |
| CMS text field | Words and URL | Padded columns | The CMS supplies heading styles, and the field is usually monospaced enough for columns to hold. |
| A plain text file you will read in two years | Words and URL | Padded columns | Nothing outside the file will explain it later, so keep every address and label each code block. |
What happens to each markdown construct
Ten constructs, and only three of them are genuinely lossy no matter what you choose. Any markdown to plain text converter has to make a call on each one. The lossy column below is worth reading before you paste something you cannot regenerate.
| Construct | Your choice | Lossy | Worth knowing |
|---|---|---|---|
| Headings | Text, underlined, or removed | Only if removed | The hashes always go. Underlining is the old plain text convention and still reads well in a monospaced file. |
| Bold, italic, strikethrough | Always unwrapped | Yes, unavoidably | There is no plain text equivalent of emphasis. The words survive and the stress does not. |
| Links | Words, words and URL, or URL | Depends on the choice | The one setting that changes a link heavy document more than any other. |
| Fenced code | Keep, label and keep, or remove | Only if removed | Contents pass through untouched. No reindenting, no trimming, no smart quotes. |
| Inline code | With or without backticks | No | Keep the backticks when a bare word would be ambiguous, such as a flag name in prose. |
| Lists | Marker style, and whether nesting is indented | Only if flattened | Ordered lists keep their numbers and their starting value, so a list beginning at 3 still begins at 3. |
| Blockquotes | Keep the marker or drop it | Yes if dropped | Dropping the marker makes somebody else words look like yours, which matters more than it sounds. |
| Tables | Padded columns, one line per cell, or comma separated | Yes, all three | A table is two dimensional and plain text is one dimensional. Pick which property you would rather keep. |
| Images | Alt text, alt and source, or removed | Yes | This is where alt text earns its keep, which is a decent argument for writing it properly. |
| Raw HTML | Strip tags or keep them | Text is kept either way | Markdown allows HTML inline, and exports from note apps are full of it. |
Construct names follow the CommonMark specification, with tables coming from the GitHub Flavored Markdown tables extension rather than CommonMark itself, which has no table syntax.
The link decision is the one that changes a document
Markdown hides an address behind words. Plain text cannot, so one of the two has to be visible and the other has to go. On a page of prose with two links, nobody notices which you picked. On a newsletter where every item is a link, keeping the addresses can add half again to the length, and dropping them makes the piece useless to the reader.
A rough rule that has held up: keep the address whenever the reader cannot come back and ask you for it. Email, an archived file, a document going to someone outside your team. Drop it when the words carry the meaning and something is enforcing a length limit, which is most application forms.
The URL only setting exists for a narrower job. If you are pulling a reading list out of a note and want the addresses to feed something else, the link text is noise. Load the newsletter sample above and switch between the three settings to see how far apart the outputs are on a document built entirely from links.
Tables and code fences pull in opposite directions
A code fence is the easy one. Its contents were never markdown, so the honest thing is to pass them through untouched. That means no reindenting, no stripping of trailing spaces, and no clever quote handling. If a line inside the fence begins with a hash it stays a hash, and if it contains a double asterisk it keeps both of them.
A table is the hard one, and there is no setting that avoids the loss. Padded columns keep the shape, which is right for a monospaced destination and wrong everywhere else, because a proportional font turns the alignment into ragged noise. One line per cell survives any font and any width, at the cost of turning a compact five row table into twenty lines. Comma separated rows are the most compact and throw the alignment away entirely.
What the converter does about this is tell you. Every lossy conversion that actually ran on your document appears in the warning list, and only the ones that ran, so a document with no tables never sees a table warning.
Why this markdown to plain text converter parses instead of stripping
Most of the quick answers to this problem are a list of regular expressions: delete leading hashes, delete pairs of asterisks, pull the label out of a link. They work on the document you tested them against and fail quietly on the next one, because a regular expression cannot tell syntax from a character that only looks like syntax.
Three failures come up constantly. A shell comment inside a fenced block starts with a hash and loses it. The expression 3 * 4 * 5 loses its asterisks to an italics rule. A URL containing underscores gets read as emphasis and comes out with pieces missing. All three are invisible until somebody downstream notices the output is wrong.
Running the document through a lexer removes the whole category. The parser already knows a fence is a fence, so nothing inside it is ever considered for a transform, and it knows a bare asterisk between digits was never emphasis in the first place. The second benefit is the reporting: once you have a token tree you can count what was in the document and say honestly which conversions cost something.
Parsing here is done with the marked lexer, which follows CommonMark with the GitHub extensions. Rendering the tokens to text is ours, and covered by 56 tests, including one that asserts a fence containing a hash and a double asterisk comes out unchanged. Thirteen of those tests exist because an adversarial review of the first version caught it discarding task list checkboxes and staying quiet about a table row the parser had already truncated.
What this converter does not do
It does not go the other way. Turning plain text back into markdown means guessing which lines were headings and which emphasis was intended, and a guess in that direction is worse than no tool at all.
It does not render your markdown either. There is no preview of the formatted document, because the output side is the plain text and a second panel would compete with it for the attention that matters.
And it does not clean up characters. If your document also carries invisible characters or curly quotes from a word processor, those pass straight through this converter untouched, because they are not markdown. The AI text cleaner is the tool for that half of the problem, and running the two in sequence covers both.
Frequently asked questions
How do I convert markdown to plain text?
Paste the document into the box above and the plain text appears beside it. A markdown to plain text converter has to decide what to do with every construct, so the settings underneath let you make those calls, and the destination presets set all of them at once for the four places people paste most often. Nothing is uploaded, so a private note stays private.
How do I strip markdown formatting for an email?
Use the email preset. It keeps link addresses visible, because a reader cannot click words that lost their URL, and it turns tables into one labelled line per cell, because mail clients rewrap text and padded columns fall apart the moment they do. Headings become plain lines, since most mail is read in a proportional font where underlining looks odd.
Will my code blocks survive the conversion?
Yes, if you leave code set to keep. The contents of a fenced block pass through character for character: no reindenting, no trimming of trailing spaces, no quote substitution. A line inside a fence that starts with a hash stays a hash rather than becoming a heading, which is the main practical reason to parse the document rather than run a regex over it.
What happens to tables when markdown becomes plain text?
Something has to give, because a table is two dimensional and plain text is not. Padded columns keep the visual shape but only line up in a monospaced font. One line per cell keeps every value readable anywhere but makes the output much longer. Comma separated rows are the most compact and lose the alignment entirely. The converter tells you which of the three it applied.
Should I keep the URL or just the link text?
Keep the URL whenever the reader cannot ask you for it later: email, an archived file, anything that leaves your hands. Drop it when the words carry the meaning and space is short, such as a form with a character limit. The awkward middle case is a document where every sentence contains a link, since keeping the addresses can double its length.
Why not just use a regular expression to remove the markdown symbols?
Because a regular expression cannot tell syntax from a character that happens to look like syntax. It will strip the hash from a shell comment inside a code fence, eat the asterisks in 3 * 4 * 5, and mangle a URL that contains an underscore. Parsing the document first means those cases never come up, and it is also what lets the tool count what it found and warn you about the lossy parts.
Does this work with Obsidian or Notion exports?
Yes for the standard constructs, with a caveat that has nothing to do with this tool. Those exports are already lossy before you get here: callouts arrive as blockquotes with an emoji at the front, toggles arrive flattened, and equations arrive as plain text. What reaches the converter is ordinary markdown, and it is handled as such. Embedded HTML is common in those files, so the HTML switch matters more than usual.
Next step
Converted text often still carries the other kind of problem: no-break spaces from a word processor, curly quotes, zero width characters that survive a copy and paste and break a search later. Those are invisible here because they are not markdown.
Related tools on OpenAI Tools Hub
AI Text Cleaner
Finds the invisible characters, odd spaces and curly quotes that markdown conversion leaves behind.
Markdown to HTML
The other direction, for when the destination understands tags rather than plain text.
Markdown Preview
See the rendered document before you decide what the plain version needs to keep.
Word Counter
Check the converted text against a form limit before you find out the hard way.
Text Diff
Compare two settings side by side to see what a table strategy actually costs.
Context Window Calculator
Plain text is cheaper in tokens than markdown. See how much more of it fits.
About the author
Jim Liu
Jim Liu runs the OpenAI Tools Hub review portfolio and writes most of it in markdown, which is how he ended up caring about what a table looks like once the pipes are gone. More about how this site tests things.