Text to HTML Converter
Paragraphs, line breaks and lists from plain text, with every character escaped before any tag is added, so AT&T and <script> come out as words.
<p>Release notes for 2.4</p>
<p>It ships faster sync & a fix for <script>alert(1)</script> in titles.<br />
Read more at <a href="https://swiftplugins.pro/changelog" rel="noopener">https://swiftplugins.pro/changelog</a> or mail <a href="mailto:[email protected]">[email protected]</a>.</p>
<ul>
<li>Faster sync</li>
<li>Fixed the import bug</li>
<li>AT&T edge case</li>
</ul>
<ol>
<li>Back up</li>
<li>Update</li>
<li>Clear the cache</li>
</ol>
<!--
Text in 268 characters
HTML out 480 characters
Paragraphs 2
List items 6
Line breaks kept as <br />
Escaping happens before any tag is added, so text containing angle
brackets or an ampersand comes out as characters rather than as markup.
The ampersand is escaped first, or the escapes of the other characters
get escaped again and you see &lt; in the output.
Links are built from the already-escaped text and only from http and
https addresses, so nothing in the input can close the attribute or
smuggle a javascript: URL into an href.
-->
Output is valid and updates as you type.
Fix the highlighted fields to update the output.
Plain text into HTML: blank lines become paragraphs, single newlines become line breaks, and lines starting with a dash or a number become list items.
The part that matters is the order. Every character is escaped before any tag is
added, so text containing <script> comes out as visible characters and AT&T
survives. Converters that add the paragraphs first escape their own tags; ones that
escape only the angle brackets leave the ampersand to be reinterpreted, and AT&T
becomes something else on the next round trip.
How to use
- Paste the text.
- Decide whether single newlines should become
<br />— off is usually right for prose, on for addresses and poetry. - Turn autolinking on if the output is going somewhere that will not linkify by itself.
Example
<p>Release notes for 2.4</p>
<p>It ships faster sync & a fix for <script>alert(1)</script> in titles.<br />
Read more at <a href="https://swiftplugins.pro/changelog" rel="noopener">https://swiftplugins.pro/changelog</a> or mail <a href="mailto:[email protected]">[email protected]</a>.</p>
<ul>
<li>Faster sync</li>
<li>Fixed the import bug</li>
<li>AT&T edge case</li>
</ul>
<ol>
<li>Back up</li>
<li>Update</li>
<li>Clear the cache</li>
</ol>
The <script> in the input is four escaped characters in the output. The ampersand in
AT&T is &. Both are what a reader will see as the original text, and neither
is markup.
Pitfalls
Escape the ampersand first. & must be replaced before < and >, or the
< you just produced becomes &lt; and the reader sees the escape rather than
the character. It is a one-line ordering bug and it is in a lot of hand-rolled
converters.
Escaping only < and > is not enough. A stray & left in the output is
interpreted by the browser, so AT&T can render as AT&T today and break the moment
something re-encodes the page. Escape all five characters.
<br /> is not a paragraph. Two sentences joined with a line break are one
paragraph to a screen reader, to a search engine and to CSS. Turn line breaks off for
prose and let the blank lines do the work.
Autolinking is a security decision. A link built from unescaped text can close the
href attribute and add an event handler. Here the pattern runs after escaping and
matches http and https only, so javascript: and data: URLs never become links.
Add nofollow for text you did not write. rel="noopener" is the default and is
about window handles. If the text came from a visitor, the rel you want is
noopener nofollow ugc.
This is not Markdown. Bold, italics, headings, links with text and code fences are not recognised, on purpose: a converter that half-implements Markdown is worse than one that does paragraphs properly. There is a Markdown tool on this site for Markdown.
Trailing whitespace disappears. Lines are trimmed, because a plain-text file’s trailing spaces are an accident rather than a meaning. The exception is a Markdown two-space line break, which this tool does not implement anyway.
Compatibility
Everything runs in the browser: nothing is uploaded and nothing is stored, which matters when the text is a customer email or an unpublished draft.
The output is plain HTML with no classes and no wrapper, so it drops into a WordPress
block, a template, an email builder or a static site without bringing anything with it.
<br /> is written in the self-closing form, which is valid in both HTML and XHTML; if
your linter prefers <br>, both parse identically.
Input is capped at 100,000 characters. Above that, convert it in sections.
This is not nl2br. nl2br adds a <br> after every newline and leaves the
paragraphs undivided; WordPress’s wpautop is closer, and it also does not escape,
because it expects content that is already trusted.
Frequently asked questions
Should I turn line breaks on or off?
Why is my apostrophe '?
Can it produce Gutenberg blocks?
Does it handle smart quotes and dashes?
What about tables?
<table> by hand or use the Markdown
tool.