Converter
Runs locally- or * starts a bulleted list. A line starting with 1. starts a numbered list.
The preview is rendered in a sandboxed frame. Scripts in your input cannot run, and nothing can reach this page.
Ready.
What this converter does
Writing HTML around prose is mechanical work: wrap each paragraph in <p>, remember to close each list item, escape the ampersands in a URL, and add rel="noopener" to every external link. This tool does that from the plain text you already have. Paste a draft, pick your options, and copy structured markup instead of retyping it.
It is deliberately small. It reads blocks — headings, paragraphs, lists — not a full document format. It does not know about tables, images, code fences or footnotes. What it does know is the shape of ordinary prose, and it turns that into semantic HTML that a CMS will accept and a screen reader can navigate.
Everything happens in this browser tab. There is no upload, no account, no logging, and no third-party script. The preview runs inside a sandboxed frame, so even if your input contains a script tag, it will not run here.
How the conversion works
The pipeline has three stages, and the order matters. Getting it wrong is what produces broken escaping and, worse, XSS.
1. Parse into blocks
The input is split on newlines and walked once. Each line is classified: blank, list item, or ordinary text. Consecutive ordinary lines join into a paragraph; consecutive list items of the same kind join into a single list. The result is a tree of blocks, each with a type and some text. No HTML has been produced yet.
2. Escape each text node
Every piece of text in every block is passed through an escaper that replaces &, <, >, " and ' with their entities. This happens before any tag is inserted, so the only angle brackets in the output are the ones the tool itself produced. Typing <script> produces the literal text <script>.
3. Add inline markup
On the escaped text, bold and italic markers are converted, then URLs, then email addresses. Each transformation inserts a known-safe tag around known-safe text. Because the text was already escaped, no user input can become a tag.
https://x.com/"><script> would have broken out of the attribute and executed in whatever page the output was pasted into. Escaping first makes that impossible regardless of what the input contains.
Line break rules
HTML collapses whitespace, so a newline in a source file is not a newline on screen. The Output structure setting decides what a newline means. The three modes exist because all three are correct for different jobs.
| Mode | Blank line | Single newline | Use when |
|---|---|---|---|
| Paragraphs (default) | New <p> |
Space inside the same paragraph | Wrapped prose. A paragraph is one idea; how the text wraps in the editor is irrelevant. |
| Paragraphs with line breaks | New <p> |
<br> inside the paragraph |
Addresses, poems, lyrics, forms — anything where a line ending is meaningful but a blank line still separates sections. |
| Line breaks only | <br> |
<br> |
Preserving the visual layout of a plain-text file exactly, with no paragraph semantics at all. |
The middle option is the one most people actually want when they switch away from the default, because the default quietly joins their lines. That is standard HTML behaviour, not a bug, but it surprises anyone coming from a word processor.
The options in detail
Escape HTML characters
On by default, and it should stay on unless you are deliberately converting markup you wrote. When it is off, the tool shows a visible warning above the status line. See the next section for the reasoning.
First line as <h1>
Consumes the first non-blank line into a heading instead of a paragraph. If the first line is a list item, the heading is skipped — a bullet point is not a title. Only one <h1> is ever produced, because a page should have exactly one top-level heading.
Detect lists
Recognises -, * and • as bullet markers, and 1. or 1) as ordered markers. Consecutive items of the same kind merge into one list. Mixing bullet and numbered lines produces two lists back to back. Nested lists are not supported — see the limitations below.
Auto-link URLs
Matches http://, https:// and ftp:// addresses, strips trailing punctuation that belongs to the sentence rather than the URL (a full stop, a comma, a closing parenthesis), and adds target="_blank" rel="noopener noreferrer" so the new tab cannot reach back through window.opener.
Auto-link email addresses
Matches a local part, an at sign, a domain, a dot and a top-level domain of two or more letters. That handles both [email protected] and [email protected]. An earlier version of this tool required two dots after the at sign and so never matched an ordinary address; that is fixed here.
Bold and italic markers
**text** becomes <strong> and *text* becomes <em>. That is the whole of the Markdown support. Underscore variants, headings written with hashes, and link syntax are not recognised — use a dedicated Markdown converter for those.
Escaping and safety
An HTML entity is a way of writing a character that would otherwise be interpreted as syntax. < renders as <. & renders as &. The browser displays the character without treating it as markup.
This matters for two reasons. The obvious one is display: if your text contains the phrase use <div> for layout, escaping keeps the angle brackets visible instead of the browser trying to render a div. The less obvious reason is security.
img tag with an onerror handler, a script tag, a javascript: link: all of it runs in the visitor's browser, in the security context of your site. That is stored XSS, and it is why the warning appears when you turn the option off. If the input came from anyone other than you, leave escaping on.
The tool never emits a javascript:, data: or vbscript: URL, because the auto-linker only matches http, https and ftp. Links it creates always carry rel="noopener noreferrer". And the preview is sandboxed, so nothing in the input can execute here even in the unsafe mode.
Worked example
This is the sample the Load sample button inserts:
Welcome to SkillsInsider This is a paragraph with **bold** and *italic* text. Visit https://skillsinsider.com for more tools. Contact us at [email protected] - First item - Second item 1. Ordered first 2. Ordered second
Parsed into blocks:
h1 Welcome to SkillsInsider p This is a paragraph with **bold** and *italic* text. / Visit https://… / Contact us at … ul First item, Second item ol Ordered first, Ordered second
Rendered, with escaping on and all options enabled:
<h1>Welcome to SkillsInsider</h1> <p>This is a paragraph with <strong>bold</strong> and <em>italic</em> text. Visit <a href="https://skillsinsider.com" target="_blank" rel="noopener noreferrer">https://skillsinsider.com</a> for more tools. Contact us at <a href="mailto:[email protected]">[email protected]</a></p> <ul> <li>First item</li> <li>Second item</li> </ul> <ol> <li>Ordered first</li> <li>Ordered second</li> </ol>
Two details are worth pointing at. The three lines inside the paragraph stay in one paragraph, with the line endings rendered as spaces — because Paragraphs is the default mode. And the email is linked, which the previous version of this tool could not do for any address with a single dot after the @.
What this converter cannot do
- No nested lists. An indented bullet under a bullet is treated as a sibling item, not a child list. Building nested lists means editing the output by hand.
- No tables. Pipe-delimited text stays as text. Use the table generator for tabular content.
- No blockquotes or code blocks. Lines starting with
>or indented by four spaces are treated as ordinary text. - No heading levels beyond one. The tool produces a single
<h1>for the first line and paragraphs for everything else. If you need<h2>and<h3>, add them after conversion or use the rich text editor. - No Markdown beyond bold and italic. No link syntax, no heading hashes, no code fences, no footnotes.
- No image handling. A line that happens to contain an image URL becomes a plain link, not an
<img>. - No Unicode normalisation. Text is passed through as typed. Smart quotes, non-breaking spaces and zero-width characters stay exactly as they were, which may be what you do not want if you copied from Word.
- It does not post-process your CMS. WordPress, Ghost and Webflow each run their own sanitiser on paste. If a tag disappears after you paste, the CMS removed it, not this tool.
Frequently asked questions
What does this converter actually do?
It reads your plain text, splits it into blocks, and wraps each block in the HTML element that matches its role. A blank line starts a new paragraph. A line beginning with a dash or asterisk starts an unordered list. A line beginning with a number and a dot starts an ordered list. An optional first-line heading becomes an <h1>. Every text node is HTML-escaped first, then bold, italic, link and email markup is added, so the output is valid HTML rather than raw text with tags sprinkled in.
How are single line breaks different from blank lines?
A blank line is a paragraph boundary and starts a new <p> element. A single line break inside a paragraph renders as a space in HTML, which is usually what you want for wrapped prose. If you need a visible line break, switch the output structure option to Paragraphs with line breaks, which inserts a <br> at each single newline inside the paragraph. If you want no paragraph elements at all and a <br> for every newline, choose Line breaks only.
Why was my email address not auto-linked?
The address must look like a complete email: a local part, an at sign, and a domain with at least one dot followed by two or more letters. If it is inside a word without a space on either side, or it uses characters outside the usual set, it will not be recognised. An earlier version of this tool required two dots after the at sign and therefore never matched an ordinary address; that is fixed here.
What does the escape option change?
When escaping is on, the characters ampersand, less-than, greater-than, double quote and single quote are replaced with their HTML entities before anything else happens. That means markup you typed appears as literal text instead of being interpreted. When escaping is off, your raw text is inserted and any HTML you typed will run as markup. The tool shows a visible warning in that mode, because pasting unescaped input from an untrusted source is an XSS risk.
Does it support Markdown?
Only two inline markers: double asterisks for bold and single asterisks for italic. It is not a Markdown parser. There is no support for headings written with hashes, links written in square-bracket syntax, code fences, tables or blockquotes. If you need those, use a dedicated Markdown converter instead.
Is the generated HTML safe to paste into my site?
That depends on your input. If escaping is on and the input is text you wrote, the output contains only the elements this tool generates: p, h1, ul, ol, li, a, strong and em. Links carry rel="noopener noreferrer" and only http, https and ftp schemes are matched. If escaping is off, whatever you typed passes through, so only use that mode for input you trust completely. Either way, review before publishing.
Can I see the rendered result before copying?
Yes. The Preview tab renders the output in a sandboxed frame, so scripts in your input cannot run and cannot reach this page. That lets you check the layout and the link targets before you paste the markup anywhere.
Is anything uploaded when I use this tool?
No. Parsing, escaping, rendering and preview all run in JavaScript on your device. There is no API call and no analytics event containing your text. You can confirm this in the Network tab: type a paragraph and check that no request appears. The page also keeps working with the network disconnected after it loads.
About this tool
Editorial and verification standards are in the editorial policy. Data handling is in the privacy policy.