Plain Text to HTML Converter
Convert plain text to clean HTML with automatic URL linking, email detection, line breaks, horizontal rules, and nested ordered/unordered list recognition.
About
Raw text pasted into a CMS or email template without proper HTML markup produces collapsed whitespace, dead links, and broken list structures. This converter parses plain text and emits semantic HTML: URLs and email addresses become clickable a elements, consecutive newlines become br tags, lines of three or more hyphens become hr elements, and indented lines prefixed with *, -, or digits resolve into properly nested ol and ul trees. The parser operates in a single pass with an indent-tracking stack, so arbitrarily deep mixed lists are handled without ambiguity. Note: the tool assumes a 2-space or 4-space indent unit for nesting depth calculation. Tabs are normalized to 4 spaces.
Formulas
The converter applies a deterministic pipeline to transform each line of input. The line classification logic follows this precedence:
For list nesting, indent depth d is computed as:
where indentUnit = 2 spaces (configurable). A stack S of tuples (depth, listType) governs open/close tag emission. When dcurrent > dprevious, a new nested list opens. When dcurrent < dprevious, lists are closed until stack depth matches.
URL detection uses the pattern: /(?:https?|ftp):\/\/[^\s<>]+|www\.[^\s<>]+/g. Email detection: /[a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,}/g. URLs within list item text and plain text lines are linkified after structural parsing is complete.
Reference Data
| Plain Text Pattern | Detected As | HTML Output | Notes |
|---|---|---|---|
| https://example.com | URL | <a href="...">...</a> | http and https supported |
| [email protected] | <a href="mailto:...">...</a> | Standard email pattern | |
| Empty line (\n\n) | Line break | <br> | Single newline also converts |
| --- | Horizontal rule | <hr> | 3 or more hyphens, nothing else on line |
| 1 Item text | Ordered list | <ol><li>...</li></ol> | Digit + space(s) |
| 1. Item text | Ordered list | <ol><li>...</li></ol> | Digit + dot + space(s) |
| * Item text | Unordered list | <ul><li>...</li></ul> | Asterisk + space(s) |
| - Item text | Unordered list | <ul><li>...</li></ul> | Hyphen + space(s), but not --- |
| * Nested | Nested unordered | Nested <ul> inside <li> | 2-space indent = 1 depth level |
| 1. Deep nested | Nested ordered | Nested <ol> inside <li> | 4-space indent = 2 depth levels (with 2-space unit) |
| Mixed: ul then ol child | Mixed nesting | <ul><li>...<ol><li>...</li></ol></li></ul> | List type tracked per depth level |
| Plain text line | Text | Text content (with <br> between lines) | No special prefix detected |
| ftp://files.example.com | URL | <a href="...">...</a> | ftp protocol also detected |
| www.example.com | URL | <a href="http://...">...</a> | Auto-prefixed with http:// |