# Markdown Rendering: Convert Markdown to HTML

# Markdown to HTML Conversion: Complete Guide

## Problem

Converting Markdown to HTML is a common requirement in web applications, documentation systems, and content management platforms. Manual conversion is error-prone and inefficient. We need a reliable, performant solution that handles various Markdown syntax elements correctly.

## Solution

Use established Markdown parsing libraries like **Marked** or **Remark** that provide robust, well-tested conversion capabilities with extensive customization options.

### Comparison: Marked vs Remark

| Feature | Marked | Remark |
|---------|--------|--------|
| **Performance** | Very fast, optimized | Slightly slower, AST-based |
| **Customization** | Token-based | Plugin ecosystem |
| **Learning Curve** | Easier | Steeper |
| **Use Case** | Quick conversions | Complex transformations |
| **Bundle Size** | ~30KB | ~50KB+ with plugins |

## Code Implementation

### 1. Using Marked (Recommended for Speed)

```javascript
// Installation
// npm install marked

import { marked } from 'marked';

// Basic conversion
const markdown = `
# Hello World
This is a **bold** text and *italic* text.

- Item 1
- Item 2
- Item 3

\`\`\`javascript
console.log('Code block');
\`\`\`
`;

const html = marked(markdown);
console.log(html);
```

**Output:**
```html
<h1>Hello World</h1>
<p>This is a <strong>bold</strong> text and <em>italic</em> text.</p>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
<pre><code class="language-javascript">console.log('Code block');
</code></pre>
```

### 2. Advanced Marked Configuration

```javascript
import { marked } from 'marked';

// Custom renderer
const renderer = {
  heading(token) {
    return `<h${token.depth} class="custom-heading">${token.text}</h${token.depth}>\n`;
  },
  link(token) {
    return `<a href="${token.href}" target="_blank" rel="noopener">${token.text}</a>`;
  },
  code(token) {
    return `<pre><code class="hljs language-${token.lang}">${token.text}</code></pre>\n`;
  }
};

marked.use({ renderer });

const html = marked('# [Visit Site](https://example.com)');
```

### 3. Using Remark (Plugin-Based)

```javascript
// Installation
// npm install remark remark-html

import { remark } from 'remark';
import remarkHtml from 'remark-html';

const markdown = `
# Heading
Paragraph with **bold** and *italic*.
`;

const file = await remark()
  .use(remarkHtml)
  .process(markdown);

console.log(String(file));
```

### 4. Remark with Multiple Plugins

```javascript
import { remark } from 'remark';
import remarkHtml from 'remark-html';
import remarkGfm from 'remark-gfm'; // GitHub Flavored Markdown
import remarkToc from 'remark-toc'; // Table of contents

const markdown = `
# My Document

## Table of Contents

## Section 1
Content here.

## Section 2
More content.

| Header 1 | Header 2 |
|----------|----------|
| Cell 1   | Cell 2   |
`;

const file = await remark()
  .use(remarkGfm)
  .use(remarkToc)
  .use(remarkHtml)
  .process(markdown);

console.log(String(file));
```

### 5. Security: Sanitizing HTML Output

```javascript
import { marked } from 'marked';
import DOMPurify from 'isomorphic-dompurify';

const unsafeMarkdown = `
# Title
<script>alert('XSS')</script>
[Click me](javascript:alert('XSS'))
`;

const html = marked(unsafeMarkdown);
const sanitized = DOMPurify.sanitize(html);

console.log(sanitized); // Safe HTML
```

### 6. Syntax Highlighting Integration

```javascript
import { marked } from 'marked';
import hljs from 'highlight.js';

marked.setOptions({
  highlight: (code, lang) => {
    if (lang && hljs.getLanguage(lang)) {
      return hljs.highlight(code, { language: lang }).value;
    }
    return hljs.highlightAuto(code).value;
  }
});

const markdown = `
\`\`\`python
def hello():
    print("Hello, World!")
\`\`\`
`;

const html = marked(markdown);
```

### 7. Full-Featured React Component

```javascript
import React, { useMemo } from 'react';
import { marked } from 'marked';
import DOMPurify from 'isomorphic-dompurify';

const MarkdownRenderer = ({ content, className = '' }) => {
  const html = useMemo(() => {
    const raw = marked(content);
    return DOMPurify.sanitize(raw);
  }, [content]);

  return (
    <div 
      className={`markdown-content ${className}`}
      dangerouslySetInnerHTML={{ __html: html }}
    />
  );
};

export default MarkdownRenderer;

// Usage
<MarkdownRenderer content="# Hello\n**Bold text**" />
```

## Tips & Best Practices

### ✅ Performance Optimization

```javascript
// Cache parsed results
const cache = new Map();

function parseMarkdown(md) {
  if (cache.has(md)) return cache.get(md);
  const html = marked(md);
  cache.set(md, html);
  return html;
}
```

### ✅ Custom Extensions

```javascript
// Add custom token types
marked.use({
  extensions: [{
    name: 'highlight',
    level: 'inline',
    start(src) { return src.match(/==/)?.index; },
    tokenizer(src) {
      const rule = /^==(.*?)==/;
      const match = rule.exec(src);
      if (match) {
        return {
          type: 'highlight',
          raw: match[0],
          text: match[1],
          tokens: []
        };
      }
    },
    renderer(token) {
      return `<mark>${token.text}</mark>`;
    }
  }]
});
```

### ✅ Error Handling

```javascript
try {
  const html = marked(markdown);
} catch (error) {
  console.error('Markdown parsing failed:', error);
  return '<p>Error rendering content</p>';
}
```

### ✅ Streaming Large Documents

```javascript
import { marked } from 'marked';

async function* streamMarkdown(markdown) {
  const tokens = marked.lexer(markdown);
  for (const token of tokens) {
    yield marked.parser([token]);
  }
}

// Usage
for await (const chunk of streamMarkdown(largeMarkdown)) {
  process.stdout.write(chunk);
}
```

### ✅ Configuration Presets

```javascript
// Preset for documentation
const docPreset = {
  breaks: true,
  gfm: true,
  pedantic: false,
  smartLists: true,
  smartypants: true
};

marked.setOptions(docPreset);

// Preset for user content
const userPreset = {
  breaks: false,
  gfm: true,
  pedantic: true
};
```

## Summary

- **Marked**: Best for speed and simplicity; ideal for most use cases
- **Remark**: Best for complex transformations and plugin ecosystems
- **Always sanitize** user-generated Markdown to prevent XSS attacks
- **Cache results** for frequently parsed content
- **Use syntax highlighting** for code blocks
- **Test edge cases** with special characters and nested structures
