/**
* Safe markdown rendering utilities.
*/
/* eslint-env browser */
import { escapeHtml } from './dom.js';
const MARKDOWN_PARSE_OPTIONS = {} as const;
/**
* Render markdown string to HTML and sanitize.
*
* - Uses `marked.parse` when available.
* - Falls back to plain text rendering when markdown parser is unavailable.
* - Applies DOMPurify when available; otherwise returns parser output as-is.
*/
export function renderSafeMarkdown(markdown: string): string {
if (!markdown) {
return '';
}
const markdownText = String(markdown);
let html: string;
try {
if (typeof marked !== 'undefined' && typeof marked.parse === 'function') {
html = marked.parse(markdownText, MARKDOWN_PARSE_OPTIONS);
} else {
throw new Error('marked not available');
}
} catch {
const fallback = escapeHtml(markdownText);
html = fallback.replace(/\n/g, '
');
}
if (typeof DOMPurify !== 'undefined' && typeof DOMPurify.sanitize === 'function') {
return DOMPurify.sanitize(html);
}
if (typeof console !== 'undefined') {
console.warn('[SafeMarkdown] DOMPurify is unavailable. Rendering escaped content as fallback.');
}
const safeFallback = escapeHtml(markdownText).replace(/\\n/g, '
');
return safeFallback;
}