Building an XMD Parser in TypeScript
typescriptparsingmarkdownxmd
A deep dive into building a custom markdown-like document format parser with TypeScript
Building an XMD Parser in TypeScript
Have you ever wanted to create your own document format? In this post, I'll walk through how I built XMD (eXtensible Markdown), a custom document format for my portfolio site.
What is XMD?
XMD is a markdown-like format that adds structured metadata and enhanced content blocks. It's designed to be:
- Simple to parse
- Type-safe with TypeScript
- Extensible for custom blocks
- Compatible with modern React components
The Building Blocks
Let's start with the core types that define our format:
01export type XMDMetadata = {02 title: string03 description: string04 date: string05 tags?: string[]06 image?: string07 featured?: boolean08}0910export type XMDBlock = {11 type: 'paragraph' | 'heading' | 'code' | 'quote'12 content: string13 level?: number // For headings14 language?: string // For code blocks15}
Parsing Strategy
The parser works in two main phases:
- Parse metadata between <code>---</code> markers
- Parse content blocks line by line
Here's a simple example:
01function parseXMD(content: string) {02 const lines = content.split('\n')03 // Parse metadata...04 // Parse blocks...05 return { metadata, blocks }06}
Using with React
The XMD format really shines when paired with React components:
01function XMDRenderer({ blocks }) {02 return (03 <article>04 {blocks.map(block => {05 switch (block.type) {06 case 'heading':07 return <h1>{block.content}</h1>08 // Handle other blocks...09 }10 })}11 </article>12 )13}
Why Not Just Use Markdown?
While Markdown is great, sometimes you need more structure and type safety.
XMD provides that while staying simple and extensible.
Key Features
- First-class TypeScript support
- Structured metadata
- Custom block types
- React component mapping
What's Next?
I'm planning to add more features to XMD:
- Nested blocks
- Custom components
- Better error handling
- Performance optimizations
Stay tuned for more updates!