BBCode Output
RichTextEditor edits and saves HTML— there is no BBCode mode built in. For forum-style or markup-constrained targets you convert the saved HTML yourself, which is a short and completely transparent function. This page runs exactly that conversion live.
BBCode produced from the editor’s saved HTML
Loading…
The converter
Own this code rather than depending on an editor mode: forum software disagrees about BBCode dialects, so the mapping belongs where you can adjust it.
function htmlToBBCode(html) {
const root = new DOMParser().parseFromString(html, "text/html").body;
const TAGS = { b: "b", strong: "b", i: "i", em: "i", u: "u",
s: "s", strike: "s", del: "s" };
function walk(node) {
if (node.nodeType === 3) return node.nodeValue; // text
if (node.nodeType !== 1) return "";
const tag = node.tagName.toLowerCase();
const inner = Array.from(node.childNodes).map(walk).join("");
if (TAGS[tag]) return `[${TAGS[tag]}]${inner}[/${TAGS[tag]}]`;
if (tag === "a") return `[url=${node.getAttribute("href") || ""}]${inner}[/url]`;
if (tag === "img") return `[img]${node.getAttribute("src") || ""}[/img]`;
if (tag === "blockquote") return `[quote]${inner.trim()}[/quote]\n`;
if (tag === "pre" || tag === "code") return `[code]${inner}[/code]`;
if (tag === "ul") return `[list]\n${inner}[/list]\n`;
if (tag === "ol") return `[list=1]\n${inner}[/list]\n`;
if (tag === "li") return `[*]${inner.trim()}\n`;
if (tag === "br") return "\n";
if (tag === "p" || tag === "div") return inner + "\n\n";
// Inline colour and size survive as style attributes.
const colour = node.style && node.style.color;
if (colour) return `[color=${colour}]${inner}[/color]`;
return inner;
}
return walk(root).replace(/\n{3,}/g, "\n\n").trim();
}
// Call it with whatever the editor saved:
const bbcode = htmlToBBCode(editor.getHTMLCode());Anything the editor produces that BBCode cannot express (tables, nested layouts, embedded media) has no faithful equivalent — decide explicitly whether to drop it or render it as a link.