fix: button rendering from RichEditor to markdown to HTML
- Added multiple htmlToMarkdown patterns for TipTap button output: 1. data-button with data-href/data-style attributes 2. Alternate attribute order (data-style before data-href) 3. Simple data-button fallback with href and class 4. Buttons wrapped in p tags (from preview HTML) 5. Direct button links without p wrapper - Button shortcodes now correctly roundtrip: RichEditor -> HTML -> [button url=... style=...] -> Preview/Email - All patterns now explicitly include style=solid for consistency
This commit is contained in:
@@ -87,7 +87,7 @@ export function markdownToHtml(markdown: string): string {
|
||||
const parsedContent = parseMarkdownBasics(content.trim());
|
||||
return `<div class="${cardClass}">${parsedContent}</div>`;
|
||||
});
|
||||
|
||||
|
||||
// Parse [card type="..."] blocks (old syntax - backward compatibility)
|
||||
html = html.replace(/\[card(?:\s+type="([^"]+)")?\]([\s\S]*?)\[\/card\]/g, (match, type, content) => {
|
||||
const cardClass = type ? `card card-${type}` : 'card';
|
||||
@@ -100,7 +100,7 @@ export function markdownToHtml(markdown: string): string {
|
||||
const buttonClass = style === 'outline' ? 'button-outline' : 'button';
|
||||
return `<p style="text-align: center;"><a href="${url}" class="${buttonClass}">${text.trim()}</a></p>`;
|
||||
});
|
||||
|
||||
|
||||
// Parse [button url="..."] shortcodes (old syntax - backward compatibility)
|
||||
html = html.replace(/\[button\s+url="([^"]+)"(?:\s+style="([^"]+)")?\]([^\[]+)\[\/button\]/g, (match, url, style, text) => {
|
||||
const buttonClass = style === 'outline' ? 'button-outline' : 'button';
|
||||
@@ -155,7 +155,7 @@ export function parseMarkdownBasics(text: string): string {
|
||||
const buttonClass = style === 'outline' ? 'button-outline' : 'button';
|
||||
return `<p style="text-align: center;"><a href="${url}" class="${buttonClass}">${text.trim()}</a></p>`;
|
||||
});
|
||||
|
||||
|
||||
// Parse [button url="..."] shortcodes (old syntax - backward compatibility)
|
||||
html = html.replace(/\[button\s+url="([^"]+)"(?:\s+style="([^"]+)")?\]([^\[]+)\[\/button\]/g, (match, url, style, text) => {
|
||||
const buttonClass = style === 'outline' ? 'button-outline' : 'button';
|
||||
@@ -267,8 +267,33 @@ export function htmlToMarkdown(html: string): string {
|
||||
});
|
||||
|
||||
// Convert buttons back to [button] syntax
|
||||
// TipTap button format with data attributes: <a data-button data-href="..." data-style="..." data-text="...">text</a>
|
||||
markdown = markdown.replace(/<a[^>]*data-button[^>]*data-href="([^"]+)"[^>]*data-style="([^"]*)"[^>]*>([^<]+)<\/a>/gi, (match, url, style, text) => {
|
||||
const styleAttr = style === 'outline' ? ' style="outline"' : ' style="solid"';
|
||||
return `[button url="${url}"${styleAttr}]${text.trim()}[/button]`;
|
||||
});
|
||||
|
||||
// Alternate order: data-style before data-href
|
||||
markdown = markdown.replace(/<a[^>]*data-button[^>]*data-style="([^"]*)"[^>]*data-href="([^"]+)"[^>]*>([^<]+)<\/a>/gi, (match, style, url, text) => {
|
||||
const styleAttr = style === 'outline' ? ' style="outline"' : ' style="solid"';
|
||||
return `[button url="${url}"${styleAttr}]${text.trim()}[/button]`;
|
||||
});
|
||||
|
||||
// Simple data-button fallback (just has href and class)
|
||||
markdown = markdown.replace(/<a[^>]*href="([^"]+)"[^>]*class="(button[^"]*)"[^>]*data-button[^>]*>([^<]+)<\/a>/gi, (match, url, className, text) => {
|
||||
const style = className.includes('outline') ? ' style="outline"' : ' style="solid"';
|
||||
return `[button url="${url}"${style}]${text.trim()}[/button]`;
|
||||
});
|
||||
|
||||
// Buttons wrapped in p tags (from preview HTML): <p><a href="..." class="button...">text</a></p>
|
||||
markdown = markdown.replace(/<p[^>]*><a href="([^"]+)" class="(button[^"]*)"[^>]*>([^<]+)<\/a><\/p>/g, (match, url, className, text) => {
|
||||
const style = className.includes('outline') ? ' style="outline"' : '';
|
||||
const style = className.includes('outline') ? ' style="outline"' : ' style="solid"';
|
||||
return `[button url="${url}"${style}]${text.trim()}[/button]`;
|
||||
});
|
||||
|
||||
// Direct button links without p wrapper
|
||||
markdown = markdown.replace(/<a href="([^"]+)" class="(button[^"]*)"[^>]*>([^<]+)<\/a>/g, (match, url, className, text) => {
|
||||
const style = className.includes('outline') ? ' style="outline"' : ' style="solid"';
|
||||
return `[button url="${url}"${style}]${text.trim()}[/button]`;
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user