# Edge Cases

Advanced scenarios and edge cases.

## Input Handling

### Empty Input

```javascript { .api }
import { marked } from "marked";

marked.parse('');              // Returns: ''
marked.parseInline('');        // Returns: ''
```

### Null/Undefined Input

```javascript { .api }
import { marked } from "marked";

try {
  marked.parse(null);          // Throws: TypeError
  marked.parse(undefined);     // Throws: TypeError
} catch (err) {
  console.error('Invalid input:', err.message);
}
```

### Large Input

```javascript { .api }
import { marked } from "marked";

// Very large inputs (>10MB) may have performance implications
const largeMarkdown = '...'; // 10MB+

console.time('parse');
const html = marked.parse(largeMarkdown);
console.timeEnd('parse');
// Typical: < 1 second for 10MB
```

### Chunked Processing

```javascript { .api }
import { marked } from "marked";

function parseInChunks(markdown, chunkSize = 100000) {
  const chunks = [];
  const paragraphs = markdown.split(/\n\n+/);
  let currentChunk = [];
  let currentSize = 0;
  
  for (const para of paragraphs) {
    if (currentSize + para.length > chunkSize && currentChunk.length > 0) {
      chunks.push(currentChunk.join('\n\n'));
      currentChunk = [];
      currentSize = 0;
    }
    currentChunk.push(para);
    currentSize += para.length;
  }
  
  if (currentChunk.length > 0) {
    chunks.push(currentChunk.join('\n\n'));
  }
  
  return chunks.map(chunk => marked.parse(chunk)).join('\n');
}
```

## Nested Structures

### Nested Links

```javascript { .api }
import { marked } from "marked";

// Links cannot contain other links (per markdown spec)
const html = marked.parse('[Outer [nested](url)](url)');
// Inner link is treated as text
```

**Explanation**: The lexer's `inLink` state prevents nested links per markdown specification.

### Deeply Nested Blockquotes

```javascript { .api }
import { marked } from "marked";

const nested = '> '.repeat(100) + 'text';
const html = marked.parse(nested);
// Handles deep nesting
```

### Deeply Nested Lists

```javascript { .api }
import { marked } from "marked";

const markdown = `
- Level 1
  - Level 2
    - Level 3
      - Level 4
        - Level 5
`;

const html = marked.parse(markdown);
// Properly handles nested lists
```

## Special Characters

### Escape Sequences

```javascript { .api }
import { marked } from "marked";

const html = marked.parse('\\* Not a list\n\\# Not a heading');
// Escaped characters rendered literally
```

### Unicode

```javascript { .api }
import { marked } from "marked";

const html = marked.parse('# 你好世界 🌍\n\nEmoji and Unicode: 😀 ñ é ü');
// Full Unicode support
```

## GFM Features

### Task Lists

```javascript { .api }
import { marked } from "marked";

marked.setOptions({ gfm: true });

const html = marked.parse(`
- [ ] Unchecked task
- [x] Checked task
- [ ] Another task
`);
```

### Tables

```javascript { .api }
import { marked } from "marked";

marked.setOptions({ gfm: true });

const html = marked.parse(`
| Left | Center | Right |
|:-----|:------:|------:|
| L    |   C    |     R |
`);
```

### Strikethrough

```javascript { .api }
import { marked } from "marked";

marked.setOptions({ gfm: true });

const html = marked.parse('~~deleted text~~');
// Output: <p><del>deleted text</del></p>
```

### Autolinks

```javascript { .api }
import { marked } from "marked";

marked.setOptions({ gfm: true });

const html = marked.parse('Visit https://example.com for more.');
// Raw URLs become clickable links
```

## Line Breaks

### Standard Markdown

```javascript { .api }
import { marked } from "marked";

marked.setOptions({ breaks: false });

const html = marked.parse('Line 1\nLine 2');
// Output: <p>Line 1\nLine 2</p> (no <br>)

const html2 = marked.parse('Line 1  \nLine 2');
// Output: <p>Line 1<br>Line 2</p> (two spaces + newline)
```

### GFM Line Breaks

```javascript { .api }
import { marked } from "marked";

marked.setOptions({ gfm: true, breaks: true });

const html = marked.parse('Line 1\nLine 2');
// Output: <p>Line 1<br>Line 2</p>
```

## HTML Blocks

### Block-Level HTML

```javascript { .api }
import { marked } from "marked";

const html = marked.parse(`
<div class="custom">
  Custom HTML block
</div>

Regular markdown continues here.
`);
// HTML passed through unchanged
```

### Inline HTML

```javascript { .api }
import { marked } from "marked";

const html = marked.parse('Text with <span class="custom">inline HTML</span>.');
// Inline HTML passed through
```

## Link References

### Reference-Style Links

```javascript { .api }
import { marked } from "marked";

const markdown = `
[Google]: https://google.com "Google Search"
[GitHub]: https://github.com

Visit [Google] or [GitHub].
`;

const html = marked.parse(markdown);
// References resolved to full links
```

### Shortcut References

```javascript { .api }
import { marked } from "marked";

const markdown = `
[Google]: https://google.com

Visit [Google].
`;

const html = marked.parse(markdown);
```

## Code Blocks

### Fenced Code

```javascript { .api }
import { marked } from "marked";

const markdown = `
\`\`\`javascript
console.log('code');
\`\`\`
`;

const html = marked.parse(markdown);
```

### Indented Code

```javascript { .api }
import { marked } from "marked";

const markdown = `
    indented code
    more code
`;

const html = marked.parse(markdown);
// 4+ spaces creates code block
```

### Multiple Backticks

```javascript { .api }
import { marked } from "marked";

const html = marked.parseInline('`` code with ` backtick ``');
// Multiple backticks for code containing backticks
```

## Empty Elements

### Empty Headings

```javascript { .api }
import { marked } from "marked";

const html = marked.parse('# \n');
// Creates empty heading
```

### Empty Links

```javascript { .api }
import { marked } from "marked";

const html = marked.parse('[](url)');
// Creates link with empty text
```

### Only Whitespace

```javascript { .api }
import { marked } from "marked";

const html = marked.parse('   \n  \n  ');
// Returns space token
```

### Only Link Definitions

```javascript { .api }
import { marked } from "marked";

const tokens = marked.lexer('[ref]: url');
console.log(tokens);        // []
console.log(tokens.links);  // { ref: { href: 'url', title: '' } }
```

## Extension Edge Cases

### Extension Stacking

```javascript { .api }
import { marked } from "marked";

// Multiple extensions handling same token type
marked.use({
  renderer: {
    link(token) {
      if (token.href.startsWith('mailto:')) {
        return `<a href="${token.href}" class="email">...</a>`;
      }
      return false; // Pass to next renderer
    }
  }
});

marked.use({
  renderer: {
    link(token) {
      if (token.href.startsWith('tel:')) {
        return `<a href="${token.href}" class="phone">...</a>`;
      }
      return false; // Pass to default
    }
  }
});
```

### Async Extension Errors

```javascript { .api }
import { marked } from "marked";

marked.use({
  async: true,
  async walkTokens(token) {
    if (token.type === 'link') {
      try {
        await validateUrl(token.href);
      } catch (err) {
        console.error('Validation error:', err);
        token.validated = false;
      }
    }
  }
});

try {
  const html = await marked.parse(markdown, { async: true });
} catch (err) {
  console.error('Parse error:', err);
}

async function validateUrl(url) {
  // Validation logic
}
```

## Performance Edge Cases

### Very Long Lines

```javascript { .api }
import { marked } from "marked";

const longLine = 'a'.repeat(100000);
const html = marked.parse(longLine);
// Handles long lines efficiently
```

### Many Small Tokens

```javascript { .api }
import { marked } from "marked";

const manyTokens = '**a** '.repeat(10000);
const html = marked.parse(manyTokens);
// Handles many tokens efficiently
```

## Token Serialization

```javascript { .api }
import { marked } from "marked";

// Convert tokens to JSON
const tokens = marked.lexer(markdown);
const json = JSON.stringify(tokens, null, 2);

// Parse back from JSON
const parsedTokens = JSON.parse(json);
parsedTokens.links = tokens.links; // Restore links

// Parse tokens
const html = marked.parser(parsedTokens);
```

## Related Documentation

- [Troubleshooting Guide](../guides/troubleshooting.md)
- [API Reference](../reference/api.md)
- [Real-World Scenarios](./real-world-scenarios.md)
