Markdown HTML integration and mixed content systems enable sophisticated document creation through seamless combination of Markdown’s simplicity with HTML’s power and flexibility. By implementing strategic HTML integration patterns, developing custom component systems, and creating robust mixed-content workflows, technical writers and developers can build comprehensive documentation platforms that leverage the best aspects of both markup languages while maintaining readability, accessibility, and maintainability across complex content architectures.

Why Master HTML Integration in Markdown?

Advanced HTML-Markdown integration provides essential capabilities for modern content creation:

  • Enhanced Layout Control: Create complex layouts and responsive designs beyond Markdown’s limitations
  • Custom Component Systems: Build reusable HTML components integrated seamlessly with Markdown content
  • Interactive Content Creation: Embed dynamic elements, forms, and JavaScript-powered interactions
  • Accessibility Enhancement: Implement proper semantic HTML and ARIA attributes for inclusive design
  • Platform Consistency: Ensure consistent rendering across different Markdown processors and output formats

Foundation HTML Integration Principles

Basic HTML in Markdown Patterns

Understanding how HTML and Markdown interact in various processors:

# Basic HTML Integration Examples

## Inline HTML Elements

Standard Markdown text with <strong>inline HTML emphasis</strong> and 
<em>styled elements</em> integrated naturally within paragraphs.

You can use <code>inline code elements</code> alongside `markdown code` 
for different styling effects and semantic meaning.

Custom styling with <span class="highlight">CSS classes</span> and 
<mark>semantic HTML elements</mark> for enhanced content presentation.

## Block-Level HTML Integration

<div class="info-box">
    <h3>Information Block</h3>
    <p>This is a complete HTML block integrated within Markdown content. 
    Standard Markdown formatting like **bold text** and *italic text* 
    still works within HTML blocks in many processors.</p>
    
    <ul>
        <li>HTML lists within blocks</li>
        <li>Mixed content capabilities</li>
        <li>Semantic structure preservation</li>
    </ul>
</div>

Regular Markdown content continues seamlessly after HTML blocks, 
maintaining document flow and readability.

## Complex Layout Integration

<section class="two-column-layout">
    <div class="column">
        <h4>Left Column Content</h4>
        
        Standard **Markdown formatting** continues to work within 
        HTML containers, providing flexible content creation options.
        
        - Markdown lists
        - Within HTML containers
        - Seamless integration
    </div>
    
    <div class="column">
        <h4>Right Column Content</h4>
        
        ```javascript
        // Code blocks also work within HTML containers
        function integration() {
            return "HTML + Markdown";
        }
        ```
        
        > Blockquotes and other Markdown elements
        > maintain their formatting within HTML structures.
    </div>
</section>

## Custom Component Integration

<article class="tutorial-step" data-step="1">
    <header class="step-header">
        <h3>Step 1: Setup Process</h3>
        <span class="step-badge">Essential</span>
    </header>
    
    <div class="step-content">
        Begin by configuring your **Markdown processor** to handle mixed content:
        
        1. Enable HTML support in processor settings
        2. Configure HTML whitelist for security
        3. Test **mixed content rendering** thoroughly
        
        <div class="code-example">
            ```bash
            # Example configuration command
            markdown-processor --enable-html --secure-mode
            ```
        </div>
        
        <div class="step-notes">
            **Important**: Always validate HTML security when accepting 
            user-generated content with mixed HTML-Markdown integration.
        </div>
    </div>
</article>

## Table Enhancement with HTML

<table class="enhanced-table" role="grid">
    <thead>
        <tr>
            <th scope="col">Feature</th>
            <th scope="col">Markdown Only</th>
            <th scope="col">HTML Enhanced</th>
            <th scope="col">Benefits</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><strong>Basic Tables</strong></td>
            <td>✅ Simple syntax</td>
            <td>✅ Enhanced styling</td>
            <td>
                <ul class="benefit-list">
                    <li>Responsive design</li>
                    <li>Custom styling</li>
                </ul>
            </td>
        </tr>
        <tr>
            <td><strong>Complex Layouts</strong></td>
            <td>❌ Limited</td>
            <td>✅ Full control</td>
            <td>
                Advanced table features:
                - Cell spanning
                - **Custom headers**
                - Interactive elements
            </td>
        </tr>
    </tbody>
</table>

## Form Integration

<form class="markdown-form" action="#" method="post">
    <fieldset>
        <legend>Contact Information Form</legend>
        
        <div class="form-group">
            <label for="name">Name:</label>
            <input type="text" id="name" name="name" required>
            <small>*Enter your full name as it should appear in documentation.*</small>
        </div>
        
        <div class="form-group">
            <label for="email">Email:</label>
            <input type="email" id="email" name="email" required>
        </div>
        
        <div class="form-group">
            <label for="content-type">Content Type:</label>
            <select id="content-type" name="content-type">
                <option value="tutorial">Tutorial Content</option>
                <option value="reference">Reference Documentation</option>
                <option value="example">Code Examples</option>
            </select>
        </div>
        
        <div class="form-group">
            <label for="description">Description:</label>
            <textarea id="description" name="description" rows="4">
Write your content description using **Markdown formatting** 
if supported by your form processor.
            </textarea>
        </div>
        
        <button type="submit" class="submit-button">Submit Content</button>
    </fieldset>
</form>

Integration continues with normal Markdown content flow...

HTML Security and Sanitization

Critical considerations for safe HTML integration:

// markdown-html-sanitizer.js - Comprehensive HTML sanitization for Markdown
class MarkdownHTMLSanitizer {
    constructor(options = {}) {
        this.options = {
            allowedTags: [
                'div', 'span', 'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
                'strong', 'em', 'code', 'pre', 'blockquote',
                'ul', 'ol', 'li', 'table', 'thead', 'tbody', 'tr', 'td', 'th',
                'a', 'img', 'br', 'hr', 'section', 'article', 'header', 'footer',
                'nav', 'aside', 'main', 'figure', 'figcaption', 'details', 'summary'
            ],
            allowedAttributes: {
                'div': ['class', 'id', 'role', 'data-*'],
                'span': ['class', 'id'],
                'a': ['href', 'title', 'target', 'rel'],
                'img': ['src', 'alt', 'title', 'width', 'height', 'loading'],
                'table': ['class', 'role'],
                'th': ['scope', 'colspan', 'rowspan'],
                'td': ['colspan', 'rowspan'],
                '*': ['class', 'id', 'aria-*', 'data-*']
            },
            allowedProtocols: ['http', 'https', 'mailto', 'tel'],
            blockScripts: true,
            blockStyles: false,
            preserveMarkdown: true,
            validateNesting: true,
            ...options
        };
        
        this.dangerousTags = ['script', 'iframe', 'object', 'embed', 'form', 'input', 'button'];
        this.selfClosingTags = ['br', 'hr', 'img', 'input', 'area', 'base', 'col', 'embed', 'link', 'meta', 'param', 'source', 'track', 'wbr'];
    }
    
    sanitizeDocument(content) {
        // Step 1: Extract and protect Markdown code blocks
        const codeBlocks = [];
        const protectedContent = content.replace(/```[\s\S]*?```|`[^`]+`/g, (match, offset) => {
            const placeholder = `__CODEBLOCK_${codeBlocks.length}__`;
            codeBlocks.push(match);
            return placeholder;
        });
        
        // Step 2: Extract and validate HTML blocks
        const htmlBlocks = this.extractHTMLBlocks(protectedContent);
        let sanitizedContent = protectedContent;
        
        // Step 3: Sanitize each HTML block
        htmlBlocks.forEach((block, index) => {
            const sanitized = this.sanitizeHTMLBlock(block.content);
            sanitizedContent = sanitizedContent.replace(block.placeholder, sanitized);
        });
        
        // Step 4: Restore code blocks
        codeBlocks.forEach((code, index) => {
            sanitizedContent = sanitizedContent.replace(`__CODEBLOCK_${index}__`, code);
        });
        
        // Step 5: Final validation and cleanup
        return this.finalValidation(sanitizedContent);
    }
    
    extractHTMLBlocks(content) {
        const htmlBlocks = [];
        const htmlRegex = /<(\w+)(?:\s[^>]*)?>([\s\S]*?)<\/\1>/gi;
        let match;
        
        while ((match = htmlRegex.exec(content)) !== null) {
            const tag = match[1].toLowerCase();
            const fullMatch = match[0];
            const innerContent = match[2];
            
            // Validate tag is allowed
            if (this.options.allowedTags.includes(tag)) {
                const placeholder = `__HTMLBLOCK_${htmlBlocks.length}__`;
                htmlBlocks.push({
                    placeholder: placeholder,
                    content: fullMatch,
                    tag: tag,
                    innerContent: innerContent
                });
                
                content = content.replace(fullMatch, placeholder);
            }
        }
        
        return htmlBlocks;
    }
    
    sanitizeHTMLBlock(htmlContent) {
        // Parse HTML and validate structure
        const doc = new DOMParser().parseFromString(`<div>${htmlContent}</div>`, 'text/html');
        const container = doc.querySelector('div');
        
        if (!container) {
            return this.escapeHTML(htmlContent);
        }
        
        // Recursively sanitize all elements
        this.sanitizeElement(container);
        
        // Return inner HTML (excluding the wrapper div)
        return container.innerHTML;
    }
    
    sanitizeElement(element) {
        const tagName = element.tagName.toLowerCase();
        
        // Remove dangerous tags entirely
        if (this.dangerousTags.includes(tagName)) {
            element.remove();
            return;
        }
        
        // Remove disallowed tags but keep content
        if (!this.options.allowedTags.includes(tagName)) {
            const parent = element.parentNode;
            while (element.firstChild) {
                parent.insertBefore(element.firstChild, element);
            }
            element.remove();
            return;
        }
        
        // Sanitize attributes
        this.sanitizeAttributes(element);
        
        // Recursively sanitize child elements
        const children = Array.from(element.children);
        children.forEach(child => this.sanitizeElement(child));
        
        // Validate nesting if enabled
        if (this.options.validateNesting) {
            this.validateNesting(element);
        }
    }
    
    sanitizeAttributes(element) {
        const tagName = element.tagName.toLowerCase();
        const allowedAttrs = this.options.allowedAttributes[tagName] || this.options.allowedAttributes['*'] || [];
        
        // Get all attributes
        const attributes = Array.from(element.attributes);
        
        attributes.forEach(attr => {
            const attrName = attr.name.toLowerCase();
            const attrValue = attr.value;
            
            let isAllowed = false;
            
            // Check if attribute is explicitly allowed
            for (const allowed of allowedAttrs) {
                if (allowed === attrName) {
                    isAllowed = true;
                    break;
                } else if (allowed.includes('*')) {
                    // Handle wildcard attributes like 'data-*' or 'aria-*'
                    const pattern = new RegExp('^' + allowed.replace('*', '.*') + '$');
                    if (pattern.test(attrName)) {
                        isAllowed = true;
                        break;
                    }
                }
            }
            
            if (!isAllowed) {
                element.removeAttribute(attrName);
                return;
            }
            
            // Sanitize attribute values
            const sanitizedValue = this.sanitizeAttributeValue(attrName, attrValue);
            if (sanitizedValue !== attrValue) {
                element.setAttribute(attrName, sanitizedValue);
            }
        });
    }
    
    sanitizeAttributeValue(attrName, value) {
        // Handle URL attributes
        if (['href', 'src', 'action'].includes(attrName)) {
            return this.sanitizeURL(value);
        }
        
        // Handle class attributes
        if (attrName === 'class') {
            return this.sanitizeClassName(value);
        }
        
        // Handle ID attributes
        if (attrName === 'id') {
            return this.sanitizeID(value);
        }
        
        // Handle data attributes
        if (attrName.startsWith('data-')) {
            return this.sanitizeDataAttribute(value);
        }
        
        // Handle ARIA attributes
        if (attrName.startsWith('aria-')) {
            return this.sanitizeAriaAttribute(value);
        }
        
        // Default: escape potentially dangerous characters
        return value.replace(/[<>"']/g, (char) => {
            const entities = { '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' };
            return entities[char] || char;
        });
    }
    
    sanitizeURL(url) {
        try {
            const parsedURL = new URL(url, window.location.href);
            
            if (this.options.allowedProtocols.includes(parsedURL.protocol.slice(0, -1))) {
                return parsedURL.href;
            } else {
                return '#'; // Return safe fallback
            }
        } catch (e) {
            // If URL parsing fails, check for relative URLs or anchors
            if (url.startsWith('#') || url.startsWith('/') || !url.includes(':')) {
                return url; // Allow relative URLs and anchors
            }
            return '#'; // Return safe fallback
        }
    }
    
    sanitizeClassName(className) {
        // Allow alphanumeric, hyphens, underscores, and spaces
        return className.replace(/[^a-zA-Z0-9\-_\s]/g, '').trim();
    }
    
    sanitizeID(id) {
        // Allow alphanumeric, hyphens, and underscores only
        return id.replace(/[^a-zA-Z0-9\-_]/g, '');
    }
    
    sanitizeDataAttribute(value) {
        // Basic data attribute sanitization
        return value.replace(/[<>"']/g, '').trim();
    }
    
    sanitizeAriaAttribute(value) {
        // ARIA attributes can contain specific values
        return value.replace(/[<>"]/g, '').trim();
    }
    
    validateNesting(element) {
        const tagName = element.tagName.toLowerCase();
        const parent = element.parentElement;
        
        if (!parent) return;
        
        const parentTag = parent.tagName.toLowerCase();
        
        // Define invalid nesting combinations
        const invalidNesting = {
            'p': ['div', 'section', 'article', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'],
            'h1': ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'],
            'h2': ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'],
            'a': ['a', 'button', 'input']
        };
        
        if (invalidNesting[parentTag] && invalidNesting[parentTag].includes(tagName)) {
            // Move element outside of invalid parent
            const grandparent = parent.parentNode;
            if (grandparent) {
                grandparent.insertBefore(element, parent.nextSibling);
            }
        }
    }
    
    finalValidation(content) {
        // Final cleanup and validation
        return content
            .replace(/__HTMLBLOCK_\d+__/g, '') // Remove any unreplaced placeholders
            .replace(/\n\s*\n\s*\n/g, '\n\n') // Normalize excessive whitespace
            .trim();
    }
    
    escapeHTML(html) {
        const div = document.createElement('div');
        div.textContent = html;
        return div.innerHTML;
    }
    
    // Public API methods
    sanitize(content) {
        return this.sanitizeDocument(content);
    }
    
    validateHTMLSafety(content) {
        const dangerousPatterns = [
            /<script[\s\S]*?<\/script>/gi,
            /javascript:/gi,
            /vbscript:/gi,
            /on\w+\s*=/gi,
            /<iframe[\s\S]*?<\/iframe>/gi,
            /<object[\s\S]*?<\/object>/gi,
            /<embed[\s\S]*?>/gi
        ];
        
        const issues = [];
        
        dangerousPatterns.forEach((pattern, index) => {
            const matches = content.match(pattern);
            if (matches) {
                issues.push({
                    type: 'security',
                    pattern: pattern.toString(),
                    matches: matches,
                    severity: 'high'
                });
            }
        });
        
        return {
            isSafe: issues.length === 0,
            issues: issues,
            recommendation: issues.length > 0 ? 'Content contains potentially dangerous HTML and should be sanitized before use.' : 'Content appears safe for use.'
        };
    }
}

// Usage examples
const sanitizer = new MarkdownHTMLSanitizer({
    allowedTags: ['div', 'p', 'h1', 'h2', 'h3', 'strong', 'em', 'code', 'a', 'img'],
    blockScripts: true,
    validateNesting: true
});

// Sanitize mixed HTML-Markdown content
const mixedContent = `
# My Document

<div class="content-block">
    This is **mixed content** with <strong>HTML tags</strong>.
    
    <script>alert('dangerous');</script>
    
    ## Subheading
    
    <p>Regular paragraph with <a href="https://example.com">safe link</a>.</p>
</div>

Normal Markdown continues here...
`;

const sanitizedContent = sanitizer.sanitize(mixedContent);
console.log(sanitizedContent);

// Validate content safety
const safetyReport = sanitizer.validateHTMLSafety(mixedContent);
console.log(safetyReport);

Advanced Component Systems

Custom HTML Component Framework

Building reusable components that integrate seamlessly with Markdown:

// markdown-component-system.js - Advanced HTML component framework for Markdown
class MarkdownComponentSystem {
    constructor(options = {}) {
        this.options = {
            componentPrefix: 'md-',
            enableNesting: true,
            allowMarkdownInComponents: true,
            validateComponents: true,
            debugMode: false,
            customComponents: {},
            ...options
        };
        
        this.components = new Map();
        this.processors = new Map();
        this.renderingContext = {
            depth: 0,
            maxDepth: 10,
            variables: new Map()
        };
        
        this.initializeDefaultComponents();
    }
    
    initializeDefaultComponents() {
        // Register built-in components
        this.registerComponent('callout', this.createCalloutComponent());
        this.registerComponent('tabs', this.createTabsComponent());
        this.registerComponent('code-example', this.createCodeExampleComponent());
        this.registerComponent('image-gallery', this.createImageGalleryComponent());
        this.registerComponent('table-wrapper', this.createTableWrapperComponent());
        this.registerComponent('info-card', this.createInfoCardComponent());
        
        // Register custom components if provided
        Object.entries(this.options.customComponents).forEach(([name, component]) => {
            this.registerComponent(name, component);
        });
    }
    
    registerComponent(name, component) {
        if (typeof component !== 'object' || !component.render) {
            throw new Error(`Component ${name} must have a render method`);
        }
        
        this.components.set(name, {
            name: name,
            render: component.render,
            validate: component.validate || (() => true),
            attributes: component.attributes || [],
            allowChildren: component.allowChildren !== false,
            selfClosing: component.selfClosing || false
        });
    }
    
    processDocument(content) {
        this.renderingContext.depth = 0;
        this.renderingContext.variables.clear();
        
        // Step 1: Extract and protect Markdown code blocks
        const { content: protectedContent, codeBlocks } = this.protectCodeBlocks(content);
        
        // Step 2: Process component syntax
        let processedContent = this.processComponents(protectedContent);
        
        // Step 3: Restore code blocks
        processedContent = this.restoreCodeBlocks(processedContent, codeBlocks);
        
        return processedContent;
    }
    
    protectCodeBlocks(content) {
        const codeBlocks = [];
        const protectedContent = content.replace(/```[\s\S]*?```|`[^`]+`/g, (match) => {
            const placeholder = `__PROTECTED_CODE_${codeBlocks.length}__`;
            codeBlocks.push(match);
            return placeholder;
        });
        
        return { content: protectedContent, codeBlocks };
    }
    
    restoreCodeBlocks(content, codeBlocks) {
        codeBlocks.forEach((code, index) => {
            content = content.replace(`__PROTECTED_CODE_${index}__`, code);
        });
        return content;
    }
    
    processComponents(content) {
        // Enhanced component syntax: <md-component-name attr="value">content</md-component-name>
        const componentRegex = new RegExp(`<${this.options.componentPrefix}([^\\s>]+)([^>]*)>([\\s\\S]*?)<\\/${this.options.componentPrefix}\\1>`, 'gi');
        
        return content.replace(componentRegex, (match, componentName, attributes, innerContent) => {
            try {
                return this.renderComponent(componentName, attributes, innerContent);
            } catch (error) {
                if (this.options.debugMode) {
                    console.error(`Error rendering component ${componentName}:`, error);
                }
                return this.renderErrorComponent(componentName, error.message);
            }
        });
    }
    
    renderComponent(componentName, attributeString, innerContent) {
        const component = this.components.get(componentName);
        
        if (!component) {
            throw new Error(`Unknown component: ${componentName}`);
        }
        
        // Check rendering depth to prevent infinite recursion
        if (this.renderingContext.depth >= this.renderingContext.maxDepth) {
            throw new Error(`Maximum component nesting depth exceeded for ${componentName}`);
        }
        
        // Parse attributes
        const attributes = this.parseAttributes(attributeString);
        
        // Validate component usage
        if (this.options.validateComponents && !component.validate(attributes, innerContent)) {
            throw new Error(`Invalid component usage for ${componentName}`);
        }
        
        // Process nested content if allowed
        let processedContent = innerContent;
        if (component.allowChildren && this.options.enableNesting) {
            this.renderingContext.depth++;
            
            if (this.options.allowMarkdownInComponents) {
                // Process nested components first, then let Markdown processor handle the rest
                processedContent = this.processComponents(innerContent);
            }
            
            this.renderingContext.depth--;
        }
        
        // Render the component
        const renderContext = {
            attributes,
            content: processedContent,
            variables: this.renderingContext.variables,
            componentName
        };
        
        return component.render(renderContext);
    }
    
    parseAttributes(attributeString) {
        const attributes = {};
        
        // Enhanced attribute parsing with support for various formats
        const attrRegex = /(\w+)(?:=(?:["']([^"']*)["']|([^\s]+)))?/g;
        let match;
        
        while ((match = attrRegex.exec(attributeString)) !== null) {
            const name = match[1];
            const value = match[2] || match[3] || true;
            attributes[name] = value;
        }
        
        return attributes;
    }
    
    createCalloutComponent() {
        return {
            attributes: ['type', 'title', 'icon', 'collapsible'],
            render: ({ attributes, content }) => {
                const type = attributes.type || 'info';
                const title = attributes.title || '';
                const icon = attributes.icon || this.getDefaultIcon(type);
                const collapsible = attributes.collapsible === 'true';
                
                const titleHtml = title ? `<div class="callout-title">${icon} ${title}</div>` : '';
                const contentClass = collapsible ? 'callout-content collapsible' : 'callout-content';
                
                return `
<div class="callout callout-${type}" role="alert">
    ${titleHtml}
    <div class="${contentClass}">
        ${content}
    </div>
</div>`;
            },
            validate: (attributes) => {
                const validTypes = ['info', 'warning', 'error', 'success', 'note'];
                return !attributes.type || validTypes.includes(attributes.type);
            }
        };
    }
    
    createTabsComponent() {
        return {
            attributes: ['default-tab'],
            render: ({ attributes, content }) => {
                const defaultTab = attributes['default-tab'] || 0;
                
                // Parse tab content (simplified - would need more robust parsing)
                const tabs = this.parseTabContent(content);
                
                let tabsHtml = '<div class="tabs-component">';
                
                // Tab headers
                tabsHtml += '<div class="tab-headers" role="tablist">';
                tabs.forEach((tab, index) => {
                    const isActive = index == defaultTab ? 'active' : '';
                    tabsHtml += `<button class="tab-header ${isActive}" 
                                        role="tab" 
                                        aria-selected="${index == defaultTab}"
                                        data-tab="${index}">
                                    ${tab.title}
                                </button>`;
                });
                tabsHtml += '</div>';
                
                // Tab content
                tabsHtml += '<div class="tab-contents">';
                tabs.forEach((tab, index) => {
                    const isActive = index == defaultTab ? 'active' : '';
                    tabsHtml += `<div class="tab-content ${isActive}" 
                                      role="tabpanel" 
                                      data-tab="${index}">
                                    ${tab.content}
                                 </div>`;
                });
                tabsHtml += '</div>';
                
                tabsHtml += '</div>';
                
                // Add JavaScript for tab functionality
                tabsHtml += `
<script>
document.addEventListener('DOMContentLoaded', function() {
    const tabComponent = document.querySelector('.tabs-component:last-of-type');
    const headers = tabComponent.querySelectorAll('.tab-header');
    const contents = tabComponent.querySelectorAll('.tab-content');
    
    headers.forEach(header => {
        header.addEventListener('click', () => {
            const tabIndex = header.dataset.tab;
            
            // Update headers
            headers.forEach(h => {
                h.classList.remove('active');
                h.setAttribute('aria-selected', 'false');
            });
            header.classList.add('active');
            header.setAttribute('aria-selected', 'true');
            
            // Update content
            contents.forEach(c => c.classList.remove('active'));
            const targetContent = tabComponent.querySelector(\`[data-tab="\${tabIndex}"]\`);
            if (targetContent) {
                targetContent.classList.add('active');
            }
        });
    });
});
</script>`;
                
                return tabsHtml;
            }
        };
    }
    
    createCodeExampleComponent() {
        return {
            attributes: ['language', 'title', 'filename', 'highlight-lines', 'copy-button'],
            render: ({ attributes, content }) => {
                const language = attributes.language || 'text';
                const title = attributes.title || '';
                const filename = attributes.filename || '';
                const highlightLines = attributes['highlight-lines'] || '';
                const copyButton = attributes['copy-button'] !== 'false';
                
                const headerContent = title || filename;
                const header = headerContent ? 
                    `<div class="code-header">
                        <span class="code-title">${headerContent}</span>
                        ${copyButton ? '<button class="copy-button" title="Copy code">📋</button>' : ''}
                     </div>` : '';
                
                return `
<div class="code-example" data-language="${language}">
    ${header}
    <pre class="code-block"><code class="language-${language}">${this.escapeHTML(content.trim())}</code></pre>
</div>`;
            }
        };
    }
    
    createImageGalleryComponent() {
        return {
            attributes: ['layout', 'columns', 'lightbox'],
            render: ({ attributes, content }) => {
                const layout = attributes.layout || 'grid';
                const columns = attributes.columns || '3';
                const lightbox = attributes.lightbox === 'true';
                
                // Parse image content
                const images = this.parseImageContent(content);
                
                let galleryHtml = `<div class="image-gallery layout-${layout}" style="--columns: ${columns}">`;
                
                images.forEach((image, index) => {
                    const lightboxAttr = lightbox ? `data-lightbox="gallery" data-index="${index}"` : '';
                    galleryHtml += `
<figure class="gallery-item">
    <img src="${image.src}" 
         alt="${image.alt || ''}" 
         title="${image.title || ''}"
         loading="lazy"
         ${lightboxAttr}>
    ${image.caption ? `<figcaption>${image.caption}</figcaption>` : ''}
</figure>`;
                });
                
                galleryHtml += '</div>';
                
                if (lightbox) {
                    galleryHtml += this.generateLightboxScript();
                }
                
                return galleryHtml;
            }
        };
    }
    
    createTableWrapperComponent() {
        return {
            attributes: ['responsive', 'sortable', 'filterable', 'pagination'],
            render: ({ attributes, content }) => {
                const responsive = attributes.responsive !== 'false';
                const sortable = attributes.sortable === 'true';
                const filterable = attributes.filterable === 'true';
                const pagination = attributes.pagination === 'true';
                
                let wrapperClass = 'table-wrapper';
                if (responsive) wrapperClass += ' responsive';
                if (sortable) wrapperClass += ' sortable';
                
                let tableHtml = `<div class="${wrapperClass}">`;
                
                if (filterable) {
                    tableHtml += `
<div class="table-controls">
    <input type="text" 
           class="table-filter" 
           placeholder="Filter table contents..."
           aria-label="Filter table">
</div>`;
                }
                
                tableHtml += content;
                
                if (pagination) {
                    tableHtml += `
<div class="table-pagination">
    <button class="pagination-prev" disabled>Previous</button>
    <span class="pagination-info">Page 1 of 1</span>
    <button class="pagination-next" disabled>Next</button>
</div>`;
                }
                
                tableHtml += '</div>';
                
                if (sortable || filterable || pagination) {
                    tableHtml += this.generateTableEnhancementScript({
                        sortable,
                        filterable,
                        pagination
                    });
                }
                
                return tableHtml;
            }
        };
    }
    
    createInfoCardComponent() {
        return {
            attributes: ['variant', 'icon', 'link', 'target'],
            render: ({ attributes, content }) => {
                const variant = attributes.variant || 'default';
                const icon = attributes.icon || '';
                const link = attributes.link || '';
                const target = attributes.target || '_self';
                
                const iconHtml = icon ? `<div class="card-icon">${icon}</div>` : '';
                const cardContent = `${iconHtml}<div class="card-content">${content}</div>`;
                
                if (link) {
                    return `
<a href="${link}" 
   target="${target}" 
   class="info-card variant-${variant} card-link">
    ${cardContent}
</a>`;
                } else {
                    return `
<div class="info-card variant-${variant}">
    ${cardContent}
</div>`;
                }
            }
        };
    }
    
    parseTabContent(content) {
        // Simplified tab parsing - would need more robust implementation
        const tabs = [];
        const lines = content.split('\n');
        let currentTab = null;
        
        lines.forEach(line => {
            const tabMatch = line.match(/^##\s+(.+)/);
            if (tabMatch) {
                if (currentTab) {
                    tabs.push(currentTab);
                }
                currentTab = {
                    title: tabMatch[1],
                    content: ''
                };
            } else if (currentTab) {
                currentTab.content += line + '\n';
            }
        });
        
        if (currentTab) {
            tabs.push(currentTab);
        }
        
        return tabs;
    }
    
    parseImageContent(content) {
        const images = [];
        const imageRegex = /!\[([^\]]*)\]\(([^)]+)\)(?:\s*"([^"]*)")?/g;
        let match;
        
        while ((match = imageRegex.exec(content)) !== null) {
            images.push({
                alt: match[1] || '',
                src: match[2],
                caption: match[3] || match[1] || ''
            });
        }
        
        return images;
    }
    
    getDefaultIcon(type) {
        const icons = {
            info: 'ℹ️',
            warning: '⚠️',
            error: '',
            success: '',
            note: '📝'
        };
        return icons[type] || '📄';
    }
    
    generateLightboxScript() {
        return `
<script>
document.addEventListener('DOMContentLoaded', function() {
    const galleryImages = document.querySelectorAll('[data-lightbox="gallery"]');
    
    galleryImages.forEach(img => {
        img.addEventListener('click', function() {
            // Simple lightbox implementation
            const lightbox = document.createElement('div');
            lightbox.className = 'lightbox';
            lightbox.innerHTML = \`
                <div class="lightbox-content">
                    <span class="lightbox-close">&times;</span>
                    <img src="\${img.src}" alt="\${img.alt}">
                    <div class="lightbox-caption">\${img.title || img.alt}</div>
                </div>
            \`;
            
            document.body.appendChild(lightbox);
            
            lightbox.addEventListener('click', function(e) {
                if (e.target === lightbox || e.target.className === 'lightbox-close') {
                    lightbox.remove();
                }
            });
        });
    });
});
</script>`;
    }
    
    generateTableEnhancementScript(features) {
        return `
<script>
document.addEventListener('DOMContentLoaded', function() {
    const tableWrapper = document.querySelector('.table-wrapper:last-of-type');
    const table = tableWrapper.querySelector('table');
    
    ${features.sortable ? this.generateSortableScript() : ''}
    ${features.filterable ? this.generateFilterableScript() : ''}
    ${features.pagination ? this.generatePaginationScript() : ''}
});
</script>`;
    }
    
    generateSortableScript() {
        return `
    // Add sorting functionality
    const headers = table.querySelectorAll('th');
    headers.forEach((header, index) => {
        header.style.cursor = 'pointer';
        header.addEventListener('click', () => sortTable(index));
    });
    
    function sortTable(columnIndex) {
        const tbody = table.querySelector('tbody');
        const rows = Array.from(tbody.rows);
        const isNumeric = rows.every(row => !isNaN(row.cells[columnIndex].textContent));
        
        rows.sort((a, b) => {
            const aVal = a.cells[columnIndex].textContent.trim();
            const bVal = b.cells[columnIndex].textContent.trim();
            
            if (isNumeric) {
                return parseFloat(aVal) - parseFloat(bVal);
            } else {
                return aVal.localeCompare(bVal);
            }
        });
        
        rows.forEach(row => tbody.appendChild(row));
    }`;
    }
    
    generateFilterableScript() {
        return `
    // Add filtering functionality
    const filterInput = tableWrapper.querySelector('.table-filter');
    filterInput.addEventListener('input', function() {
        const filterValue = this.value.toLowerCase();
        const rows = table.querySelectorAll('tbody tr');
        
        rows.forEach(row => {
            const text = row.textContent.toLowerCase();
            row.style.display = text.includes(filterValue) ? '' : 'none';
        });
    });`;
    }
    
    generatePaginationScript() {
        return `
    // Add pagination functionality
    const rowsPerPage = 10;
    let currentPage = 1;
    const rows = Array.from(table.querySelectorAll('tbody tr'));
    const totalPages = Math.ceil(rows.length / rowsPerPage);
    
    function showPage(page) {
        const start = (page - 1) * rowsPerPage;
        const end = start + rowsPerPage;
        
        rows.forEach((row, index) => {
            row.style.display = (index >= start && index < end) ? '' : 'none';
        });
        
        document.querySelector('.pagination-info').textContent = 
            \`Page \${page} of \${totalPages}\`;
        
        document.querySelector('.pagination-prev').disabled = page === 1;
        document.querySelector('.pagination-next').disabled = page === totalPages;
    }
    
    document.querySelector('.pagination-prev').addEventListener('click', () => {
        if (currentPage > 1) {
            currentPage--;
            showPage(currentPage);
        }
    });
    
    document.querySelector('.pagination-next').addEventListener('click', () => {
        if (currentPage < totalPages) {
            currentPage++;
            showPage(currentPage);
        }
    });
    
    showPage(1);`;
    }
    
    renderErrorComponent(componentName, errorMessage) {
        return `
<div class="component-error" role="alert">
    <strong>Component Error:</strong> Failed to render "${componentName}" component.
    ${this.options.debugMode ? `<br><em>Error: ${errorMessage}</em>` : ''}
</div>`;
    }
    
    escapeHTML(html) {
        const div = document.createElement('div');
        div.textContent = html;
        return div.innerHTML;
    }
    
    // Public API
    process(content) {
        return this.processDocument(content);
    }
    
    addComponent(name, component) {
        this.registerComponent(name, component);
    }
    
    removeComponent(name) {
        this.components.delete(name);
    }
    
    listComponents() {
        return Array.from(this.components.keys());
    }
    
    setVariable(name, value) {
        this.renderingContext.variables.set(name, value);
    }
    
    getVariable(name) {
        return this.renderingContext.variables.get(name);
    }
}

// Usage example
const componentSystem = new MarkdownComponentSystem({
    componentPrefix: 'md-',
    enableNesting: true,
    allowMarkdownInComponents: true,
    debugMode: true
});

// Example document with custom components
const documentContent = `
# Advanced Content Example

<md-callout type="info" title="Getting Started">
This is an **informational callout** with Markdown formatting support.

- Feature 1
- Feature 2
- Feature 3
</md-callout>

<md-tabs default-tab="0">
## JavaScript Example

\`\`\`javascript
function example() {
    console.log("Tab content with code");
}
\`\`\`

## Python Example

\`\`\`python
def example():
    print("Python code example")
\`\`\`
</md-tabs>

<md-code-example language="html" title="Component Usage" copy-button="true">
<md-callout type="success">
    Nested components work seamlessly!
</md-callout>
</md-code-example>

Regular **Markdown content** continues normally between components.
`;

const processedContent = componentSystem.process(documentContent);
console.log(processedContent);

Responsive Design Integration

CSS Framework for HTML-Markdown Integration

Comprehensive styling system for mixed content:

/* markdown-html-integration.css - Complete styling for mixed HTML-Markdown content */

/* Base responsive grid system for HTML components */
.markdown-content {
    max-width: 1200px;
    margin: 0 auto;
    padding: 1rem;
    line-height: 1.6;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

/* Component container base styles */
.component-wrapper {
    margin: 2rem 0;
    position: relative;
}

/* Two-column responsive layout */
.two-column-layout {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 2rem;
    margin: 2rem 0;
}

.column {
    padding: 1rem;
    border-radius: 8px;
    background: #f8f9fa;
    border-left: 4px solid #007bff;
}

@media (max-width: 768px) {
    .two-column-layout {
        grid-template-columns: 1fr;
        gap: 1rem;
    }
}

/* Enhanced table styling */
.enhanced-table {
    width: 100%;
    border-collapse: collapse;
    margin: 1.5rem 0;
    background: white;
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.enhanced-table th,
.enhanced-table td {
    padding: 1rem;
    text-align: left;
    border-bottom: 1px solid #e9ecef;
}

.enhanced-table th {
    background: #495057;
    color: white;
    font-weight: 600;
    position: sticky;
    top: 0;
    z-index: 10;
}

.enhanced-table tbody tr:hover {
    background: #f8f9fa;
}

.enhanced-table .benefit-list {
    margin: 0;
    padding-left: 1rem;
    list-style: none;
}

.enhanced-table .benefit-list li {
    padding: 0.25rem 0;
    position: relative;
}

.enhanced-table .benefit-list li::before {
    content: '✓';
    color: #28a745;
    font-weight: bold;
    position: absolute;
    left: -1rem;
}

/* Responsive table wrapper */
.table-wrapper {
    overflow-x: auto;
    margin: 1.5rem 0;
    border: 1px solid #dee2e6;
    border-radius: 8px;
}

.table-wrapper.responsive table {
    min-width: 600px;
}

/* Table controls styling */
.table-controls {
    padding: 1rem;
    background: #f8f9fa;
    border-bottom: 1px solid #dee2e6;
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 1rem;
}

.table-filter {
    flex: 1;
    min-width: 200px;
    padding: 0.5rem;
    border: 1px solid #ced4da;
    border-radius: 4px;
    font-size: 0.9rem;
}

.table-pagination {
    padding: 1rem;
    background: #f8f9fa;
    border-top: 1px solid #dee2e6;
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
}

.pagination-prev,
.pagination-next {
    padding: 0.5rem 1rem;
    background: #007bff;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    transition: background-color 0.2s;
}

.pagination-prev:disabled,
.pagination-next:disabled {
    background: #6c757d;
    cursor: not-allowed;
}

.pagination-prev:hover:not(:disabled),
.pagination-next:hover:not(:disabled) {
    background: #0056b3;
}

.pagination-info {
    font-size: 0.9rem;
    color: #6c757d;
    min-width: 100px;
    text-align: center;
}

/* Form integration styling */
.markdown-form {
    background: white;
    padding: 2rem;
    border-radius: 8px;
    border: 1px solid #dee2e6;
    margin: 2rem 0;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}

.markdown-form fieldset {
    border: none;
    padding: 0;
    margin: 0;
}

.markdown-form legend {
    font-size: 1.25rem;
    font-weight: 600;
    color: #495057;
    margin-bottom: 1.5rem;
    padding-bottom: 0.5rem;
    border-bottom: 2px solid #e9ecef;
    width: 100%;
}

.form-group {
    margin-bottom: 1.5rem;
}

.form-group label {
    display: block;
    margin-bottom: 0.5rem;
    font-weight: 600;
    color: #495057;
}

.form-group input,
.form-group select,
.form-group textarea {
    width: 100%;
    padding: 0.75rem;
    border: 1px solid #ced4da;
    border-radius: 4px;
    font-size: 1rem;
    transition: border-color 0.2s, box-shadow 0.2s;
}

.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
    border-color: #007bff;
    box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
    outline: none;
}

.form-group small {
    display: block;
    margin-top: 0.5rem;
    color: #6c757d;
    font-size: 0.875rem;
}

.submit-button {
    background: #28a745;
    color: white;
    padding: 0.75rem 1.5rem;
    border: none;
    border-radius: 4px;
    font-size: 1rem;
    font-weight: 600;
    cursor: pointer;
    transition: background-color 0.2s;
}

.submit-button:hover {
    background: #218838;
}

/* Custom component styling */
.callout {
    padding: 1.5rem;
    margin: 1.5rem 0;
    border-radius: 8px;
    border-left: 4px solid;
    position: relative;
}

.callout-info {
    background: #e7f3ff;
    border-color: #007bff;
}

.callout-warning {
    background: #fff3cd;
    border-color: #ffc107;
}

.callout-error {
    background: #f8d7da;
    border-color: #dc3545;
}

.callout-success {
    background: #d4edda;
    border-color: #28a745;
}

.callout-note {
    background: #f8f9fa;
    border-color: #6c757d;
}

.callout-title {
    font-weight: 600;
    margin-bottom: 1rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.callout-content {
    margin: 0;
}

.callout-content.collapsible {
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.3s ease;
}

/* Tabs component styling */
.tabs-component {
    margin: 2rem 0;
    border: 1px solid #dee2e6;
    border-radius: 8px;
    overflow: hidden;
}

.tab-headers {
    display: flex;
    background: #f8f9fa;
    border-bottom: 1px solid #dee2e6;
    flex-wrap: wrap;
}

.tab-header {
    flex: 1;
    min-width: 120px;
    padding: 1rem;
    background: none;
    border: none;
    cursor: pointer;
    font-size: 0.9rem;
    font-weight: 500;
    color: #6c757d;
    transition: all 0.2s;
    border-bottom: 3px solid transparent;
}

.tab-header:hover {
    background: #e9ecef;
}

.tab-header.active {
    background: white;
    color: #007bff;
    border-bottom-color: #007bff;
}

.tab-contents {
    background: white;
}

.tab-content {
    display: none;
    padding: 2rem;
}

.tab-content.active {
    display: block;
}

/* Code example component styling */
.code-example {
    margin: 1.5rem 0;
    border-radius: 8px;
    overflow: hidden;
    border: 1px solid #e1e8ed;
}

.code-header {
    background: #f8f9fa;
    padding: 0.75rem 1rem;
    border-bottom: 1px solid #e1e8ed;
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 0.9rem;
    font-weight: 600;
    color: #495057;
}

.code-title {
    flex: 1;
}

.copy-button {
    background: none;
    border: none;
    cursor: pointer;
    padding: 0.25rem 0.5rem;
    border-radius: 4px;
    transition: background-color 0.2s;
}

.copy-button:hover {
    background: #e9ecef;
}

.code-block {
    margin: 0;
    padding: 1rem;
    background: #f8f9fa;
    font-family: 'Fira Code', 'Monaco', 'Menlo', monospace;
    font-size: 0.9rem;
    line-height: 1.5;
    overflow-x: auto;
}

/* Image gallery styling */
.image-gallery {
    margin: 2rem 0;
}

.image-gallery.layout-grid {
    display: grid;
    grid-template-columns: repeat(var(--columns, 3), 1fr);
    gap: 1rem;
}

.gallery-item {
    margin: 0;
    background: white;
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    transition: transform 0.2s;
}

.gallery-item:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.gallery-item img {
    width: 100%;
    height: 200px;
    object-fit: cover;
    cursor: pointer;
}

.gallery-item figcaption {
    padding: 1rem;
    font-size: 0.9rem;
    color: #495057;
}

/* Info card styling */
.info-card {
    display: block;
    padding: 1.5rem;
    margin: 1rem 0;
    background: white;
    border: 1px solid #dee2e6;
    border-radius: 8px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
    transition: all 0.2s;
}

.info-card.card-link {
    text-decoration: none;
    color: inherit;
    cursor: pointer;
}

.info-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.info-card.variant-primary {
    border-color: #007bff;
    background: linear-gradient(135deg, #e7f3ff 0%, #ffffff 100%);
}

.info-card.variant-success {
    border-color: #28a745;
    background: linear-gradient(135deg, #d4edda 0%, #ffffff 100%);
}

.info-card.variant-warning {
    border-color: #ffc107;
    background: linear-gradient(135deg, #fff3cd 0%, #ffffff 100%);
}

.card-icon {
    font-size: 2rem;
    margin-bottom: 1rem;
    text-align: center;
}

.card-content {
    flex: 1;
}

/* Lightbox styling */
.lightbox {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.9);
    display: flex;
    justify-content: center;
    align-items: center;
    z-index: 1000;
    opacity: 0;
    animation: fadeIn 0.3s forwards;
}

@keyframes fadeIn {
    to { opacity: 1; }
}

.lightbox-content {
    position: relative;
    max-width: 90%;
    max-height: 90%;
}

.lightbox-content img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

.lightbox-close {
    position: absolute;
    top: -40px;
    right: 0;
    color: white;
    font-size: 2rem;
    cursor: pointer;
    line-height: 1;
}

.lightbox-caption {
    position: absolute;
    bottom: -40px;
    left: 0;
    right: 0;
    color: white;
    text-align: center;
    font-size: 0.9rem;
}

/* Component error styling */
.component-error {
    background: #f8d7da;
    color: #721c24;
    padding: 1rem;
    margin: 1rem 0;
    border: 1px solid #f5c6cb;
    border-radius: 4px;
    font-size: 0.9rem;
}

/* Mobile responsive adjustments */
@media (max-width: 768px) {
    .markdown-content {
        padding: 0.5rem;
    }
    
    .image-gallery.layout-grid {
        grid-template-columns: 1fr;
    }
    
    .tab-headers {
        flex-direction: column;
    }
    
    .tab-header {
        flex: none;
    }
    
    .table-controls {
        flex-direction: column;
        align-items: stretch;
    }
    
    .table-filter {
        min-width: auto;
    }
    
    .callout,
    .info-card,
    .code-example {
        margin-left: -0.5rem;
        margin-right: -0.5rem;
        border-radius: 0;
    }
}

/* Print styles for mixed content */
@media print {
    .lightbox,
    .copy-button,
    .tab-headers,
    .table-controls,
    .table-pagination {
        display: none !important;
    }
    
    .tab-content {
        display: block !important;
        page-break-inside: avoid;
    }
    
    .callout,
    .info-card,
    .code-example {
        page-break-inside: avoid;
        border: 1px solid #000;
        background: white !important;
    }
    
    .enhanced-table {
        font-size: 0.8rem;
    }
    
    .image-gallery.layout-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

/* High contrast mode support */
@media (prefers-contrast: high) {
    .callout,
    .info-card,
    .enhanced-table,
    .code-example {
        border: 2px solid;
        background: white;
    }
    
    .tab-header.active {
        background: highlight;
        color: highlighttext;
    }
}

/* Reduced motion support */
@media (prefers-reduced-motion: reduce) {
    .gallery-item,
    .info-card,
    .callout-content,
    .lightbox {
        transition: none;
    }
    
    .lightbox {
        animation: none;
        opacity: 1;
    }
}

/* Focus management for keyboard navigation */
.tab-header:focus,
.copy-button:focus,
.gallery-item img:focus,
.info-card:focus {
    outline: 2px solid #007bff;
    outline-offset: 2px;
}

/* Skip links for accessibility */
.skip-to-content {
    position: absolute;
    top: -40px;
    left: 6px;
    background: #000;
    color: white;
    padding: 8px;
    text-decoration: none;
    z-index: 1000;
    border-radius: 4px;
}

.skip-to-content:focus {
    top: 6px;
}

Platform-Specific Integration Patterns

Jekyll and Liquid Integration

Advanced Jekyll integration with HTML components:

<!-- _includes/html-component-handler.liquid -->
<!-- Enhanced HTML component processor for Jekyll -->

{% comment %}
Usage: {% include html-component-handler.liquid content=page.content %}
{% endcomment %}

{% assign processed_content = include.content %}

<!-- Process custom HTML components -->
{% assign component_types = 'callout,tabs,code-example,gallery,info-card' | split: ',' %}

{% for component_type in component_types %}
    {% case component_type %}
        {% when 'callout' %}
            {% assign processed_content = processed_content | replace: '<md-callout', '<div class="callout' %}
            {% assign processed_content = processed_content | replace: '</md-callout>', '</div>' %}
        {% when 'tabs' %}
            {% assign processed_content = processed_content | replace: '<md-tabs', '<div class="tabs-component' %}
            {% assign processed_content = processed_content | replace: '</md-tabs>', '</div>' %}
        {% when 'code-example' %}
            {% assign processed_content = processed_content | replace: '<md-code-example', '<div class="code-example' %}
            {% assign processed_content = processed_content | replace: '</md-code-example>', '</div>' %}
    {% endcase %}
{% endfor %}

<!-- Process enhanced attributes -->
{% assign processed_content = processed_content | replace: 'type="info"', 'class="callout-info"' %}
{% assign processed_content = processed_content | replace: 'type="warning"', 'class="callout-warning"' %}
{% assign processed_content = processed_content | replace: 'type="error"', 'class="callout-error"' %}

<!-- Enhanced table processing -->
{% if processed_content contains '<table' %}
    {% assign enhanced_tables = processed_content | split: '<table' %}
    {% assign rebuilt_content = enhanced_tables[0] %}
    
    {% for table_part in enhanced_tables offset:1 %}
        {% if table_part contains 'class="enhanced"' %}
            {% assign rebuilt_content = rebuilt_content | append: '<div class="table-wrapper responsive"><table class="enhanced-table"' | append: table_part %}
            {% assign rebuilt_content = rebuilt_content | append: '</div>' %}
        {% else %}
            {% assign rebuilt_content = rebuilt_content | append: '<table' | append: table_part %}
        {% endif %}
    {% endfor %}
    
    {% assign processed_content = rebuilt_content %}
{% endif %}

<!-- Output processed content -->
{{ processed_content }}

<!-- Add required JavaScript for interactive components -->
<script>
document.addEventListener('DOMContentLoaded', function() {
    // Initialize tabs
    const tabComponents = document.querySelectorAll('.tabs-component');
    tabComponents.forEach(component => {
        initializeTabs(component);
    });
    
    // Initialize copy buttons
    const copyButtons = document.querySelectorAll('.copy-button');
    copyButtons.forEach(button => {
        initializeCopyButton(button);
    });
    
    // Initialize enhanced tables
    const enhancedTables = document.querySelectorAll('.enhanced-table');
    enhancedTables.forEach(table => {
        initializeTableEnhancements(table);
    });
});

function initializeTabs(component) {
    const headers = component.querySelectorAll('.tab-header');
    const contents = component.querySelectorAll('.tab-content');
    
    headers.forEach((header, index) => {
        header.addEventListener('click', () => {
            // Remove active class from all
            headers.forEach(h => h.classList.remove('active'));
            contents.forEach(c => c.classList.remove('active'));
            
            // Add active class to clicked
            header.classList.add('active');
            contents[index].classList.add('active');
        });
    });
}

function initializeCopyButton(button) {
    button.addEventListener('click', () => {
        const codeBlock = button.closest('.code-example').querySelector('code');
        if (codeBlock) {
            navigator.clipboard.writeText(codeBlock.textContent).then(() => {
                button.textContent = '✓ Copied!';
                setTimeout(() => {
                    button.textContent = '📋';
                }, 2000);
            });
        }
    });
}

function initializeTableEnhancements(table) {
    // Add sorting to headers
    const headers = table.querySelectorAll('th');
    headers.forEach((header, index) => {
        header.style.cursor = 'pointer';
        header.addEventListener('click', () => sortTable(table, index));
    });
}

function sortTable(table, columnIndex) {
    const tbody = table.querySelector('tbody');
    const rows = Array.from(tbody.rows);
    
    const isNumeric = rows.every(row => {
        const cellText = row.cells[columnIndex].textContent.trim();
        return !isNaN(cellText) && cellText !== '';
    });
    
    rows.sort((a, b) => {
        const aVal = a.cells[columnIndex].textContent.trim();
        const bVal = b.cells[columnIndex].textContent.trim();
        
        if (isNumeric) {
            return parseFloat(aVal) - parseFloat(bVal);
        } else {
            return aVal.localeCompare(bVal);
        }
    });
    
    rows.forEach(row => tbody.appendChild(row));
}
</script>

Hugo Shortcode Integration

Creating powerful shortcodes for HTML-Markdown integration:

<!-- layouts/shortcodes/enhanced-content.html -->
{{ $type := .Get "type" | default "info" }}
{{ $title := .Get "title" }}
{{ $icon := .Get "icon" }}
{{ $collapsible := .Get "collapsible" | default false }}

{{ $validTypes := slice "info" "warning" "error" "success" "note" }}
{{ $type = cond (in $validTypes $type) $type "info" }}

<div class="callout callout-{{ $type }}" role="alert">
    {{ if $title }}
        <div class="callout-title">
            {{ with $icon }}{{ . }}{{ end }}
            {{ $title }}
        </div>
    {{ end }}
    
    <div class="callout-content{{ if $collapsible }} collapsible{{ end }}">
        {{ .Inner | markdownify }}
    </div>
</div>

<!-- layouts/shortcodes/tabs.html -->
{{ $defaultTab := .Get "default" | default 0 }}
{{ $tabs := split .Inner "---" }}

<div class="tabs-component">
    <div class="tab-headers" role="tablist">
        {{ range $index, $tab := $tabs }}
            {{ $parts := split $tab ":" }}
            {{ $title := index $parts 0 | trim }}
            {{ $isActive := eq $index (int $defaultTab) }}
            
            <button class="tab-header{{ if $isActive }} active{{ end }}" 
                    role="tab" 
                    aria-selected="{{ $isActive }}"
                    data-tab="{{ $index }}">
                {{ $title }}
            </button>
        {{ end }}
    </div>
    
    <div class="tab-contents">
        {{ range $index, $tab := $tabs }}
            {{ $parts := split $tab ":" }}
            {{ $content := index $parts 1 | default "" | trim }}
            {{ $isActive := eq $index (int $defaultTab) }}
            
            <div class="tab-content{{ if $isActive }} active{{ end }}" 
                 role="tabpanel" 
                 data-tab="{{ $index }}">
                {{ $content | markdownify }}
            </div>
        {{ end }}
    </div>
</div>

<!-- layouts/shortcodes/code-example.html -->
{{ $language := .Get "language" | default "text" }}
{{ $title := .Get "title" }}
{{ $filename := .Get "filename" }}
{{ $copyButton := .Get "copy-button" | default true }}

{{ $headerContent := $title | default $filename }}

<div class="code-example" data-language="{{ $language }}">
    {{ if $headerContent }}
        <div class="code-header">
            <span class="code-title">{{ $headerContent }}</span>
            {{ if $copyButton }}
                <button class="copy-button" title="Copy code">📋</button>
            {{ end }}
        </div>
    {{ end }}
    
    <pre class="code-block"><code class="language-{{ $language }}">{{ .Inner | htmlEscape }}</code></pre>
</div>

<!-- layouts/shortcodes/gallery.html -->
{{ $layout := .Get "layout" | default "grid" }}
{{ $columns := .Get "columns" | default "3" }}
{{ $lightbox := .Get "lightbox" | default false }}

<div class="image-gallery layout-{{ $layout }}" style="--columns: {{ $columns }}">
    {{ range $index, $image := split .Inner "\n" }}
        {{ if $image }}
            {{ $parts := split $image "|" }}
            {{ $src := index $parts 0 | trim }}
            {{ $alt := index $parts 1 | default "" | trim }}
            {{ $caption := index $parts 2 | default $alt | trim }}
            
            {{ if $src }}
                <figure class="gallery-item">
                    <img src="{{ $src }}" 
                         alt="{{ $alt }}" 
                         loading="lazy"
                         {{ if $lightbox }}data-lightbox="gallery" data-index="{{ $index }}"{{ end }}>
                    {{ if $caption }}
                        <figcaption>{{ $caption | markdownify }}</figcaption>
                    {{ end }}
                </figure>
            {{ end }}
        {{ end }}
    {{ end }}
</div>

{{ if $lightbox }}
    {{ partial "lightbox-script.html" . }}
{{ end }}

Integration with Modern Documentation Systems

HTML-Markdown integration complements comprehensive documentation workflows. When combined with automated content validation and quality assurance, mixed content systems enable systematic verification of HTML components, accessibility compliance testing, and consistent formatting across complex documentation architectures.

For enhanced content organization, HTML integration works effectively with advanced table systems and performance optimization to create sophisticated data presentation interfaces that combine Markdown simplicity with HTML’s advanced layout capabilities, enabling complex data visualization within standard Markdown workflows.

When developing comprehensive content platforms, HTML-Markdown integration supports Progressive Web App documentation systems by providing offline-capable interactive components, cached HTML processing, and enhanced user interfaces that maintain functionality across different network conditions and device capabilities.

Conclusion

Markdown HTML integration and mixed content systems transform static documentation into dynamic, interactive experiences that leverage the strengths of both markup languages while maintaining accessibility, performance, and maintainability. By implementing comprehensive HTML sanitization, building reusable component systems, and establishing robust integration patterns, technical teams can create sophisticated content platforms that scale effectively across complex documentation requirements.

The key to successful HTML-Markdown integration lies in establishing clear security boundaries, implementing consistent component architectures, and maintaining semantic HTML practices that enhance rather than compromise accessibility. Whether you’re building technical documentation, educational content, or complex reference materials, the integration techniques covered in this guide provide the foundation for creating powerful, flexible content systems that combine Markdown’s simplicity with HTML’s advanced capabilities.

Remember to prioritize security when accepting mixed content, implement comprehensive testing for cross-platform compatibility, and establish clear guidelines for HTML usage within your Markdown workflows. With proper implementation of HTML-Markdown integration systems, your content can achieve new levels of interactivity and sophistication while maintaining the readability and maintainability that makes Markdown an ideal choice for technical documentation.