import { EmailBlock } from './types';
/**
* Convert blocks to [card] syntax HTML
*/
export function blocksToHTML(blocks: EmailBlock[]): string {
return blocks.map(block => {
switch (block.type) {
case 'card':
if (block.cardType === 'default') {
return `[card]\n${block.content}\n[/card]`;
}
return `[card type="${block.cardType}"]\n${block.content}\n[/card]`;
case 'button':
const buttonClass = block.style === 'solid' ? 'button' : 'button-outline';
return `
${block.text}
`;
case 'divider':
return `
`;
case 'spacer':
return ``;
default:
return '';
}
}).join('\n\n');
}
/**
* Convert [card] syntax HTML to blocks
*/
export function htmlToBlocks(html: string): EmailBlock[] {
const blocks: EmailBlock[] = [];
let blockId = 0;
// Split by [card] tags and other elements
const cardRegex = /\[card([^\]]*)\](.*?)\[\/card\]/gs;
const parts: string[] = [];
let lastIndex = 0;
let match;
while ((match = cardRegex.exec(html)) !== null) {
// Add content before card
if (match.index > lastIndex) {
const beforeContent = html.substring(lastIndex, match.index).trim();
if (beforeContent) parts.push(beforeContent);
}
// Add card
parts.push(match[0]);
lastIndex = match.index + match[0].length;
}
// Add remaining content
if (lastIndex < html.length) {
const remaining = html.substring(lastIndex).trim();
if (remaining) parts.push(remaining);
}
// Process each part
for (const part of parts) {
const id = `block-${Date.now()}-${blockId++}`;
// Check if it's a card
const cardMatch = part.match(/\[card([^\]]*)\](.*?)\[\/card\]/s);
if (cardMatch) {
const attributes = cardMatch[1];
const content = cardMatch[2].trim();
const typeMatch = attributes.match(/type=["']([^"']+)["']/);
const cardType = (typeMatch ? typeMatch[1] : 'default') as any;
blocks.push({
id,
type: 'card',
cardType,
content
});
continue;
}
// Check if it's a button
if (part.includes('class="button"') || part.includes('class="button-outline"')) {
const buttonMatch = part.match(/]*href="([^"]*)"[^>]*class="(button[^"]*)"[^>]*>([^<]*)<\/a>/);
if (buttonMatch) {
blocks.push({
id,
type: 'button',
text: buttonMatch[3],
link: buttonMatch[1],
style: buttonMatch[2].includes('outline') ? 'outline' : 'solid'
});
continue;
}
}
// Check if it's a divider
if (part.includes('