Skip to content

How Markdown Works

Understanding how Markdown works can help you make better use of this powerful tool. This chapter will dive into how Markdown is transformed from plain text into beautiful, formatted documents.

Basic Workflow

The Markdown workflow can be summarized in the following steps:

Markdown source file (.md) → Markdown parser → HTML document → Browser rendering

1. Writing the Markdown Source File

You use any text editor to create a .md file and write content using Markdown syntax:

markdown
# My Document

This is an **important** paragraph.

## List Example

- Item 1
- Item 2
- Item 3

2. Markdown Parser Processing

The parser reads the Markdown file, recognizes syntax elements, and converts them to corresponding HTML:

html
<h1>My Document</h1>
<p>This is an <strong>important</strong> paragraph.</p>
<h2>List Example</h2>
<ul>
  <li>Item 1</li>
  <li>Item 2</li>
  <li>Item 3</li>
</ul>

3. Browser Rendering

The generated HTML is displayed as a formatted document in the browser.

How Parsers Work

Lexical Analysis

The parser first performs lexical analysis, breaking the Markdown text into tokens:

  • # recognized as a heading token
  • **text** recognized as a bold token
  • - item recognized as a list item token

Syntax Parsing

Then it performs syntax parsing to build an Abstract Syntax Tree (AST):

Document
├── Heading (level 1): "My Document"
├── Paragraph
│   ├── Text: "This is an"
│   ├── Bold: "important"
│   └── Text: "paragraph."
├── Heading (level 2): "List Example"
└── Unordered List
    ├── List Item: "Item 1"
    ├── List Item: "Item 2"
    └── List Item: "Item 3"

HTML Generation

Finally, the syntax tree is traversed to generate the corresponding HTML output.

Mainstream Parsers

CommonMark

  • Standard specification - Provides a unified Markdown parsing standard
  • Strictly defined - Eliminates ambiguities between different implementations
  • Widely supported - Adopted by multiple parsers

GitHub Flavored Markdown (GFM)

Based on CommonMark, with additions:

  • Table support
  • Strikethrough
  • Task lists
  • Autolink detection
  • Syntax-highlighted code blocks

Other Parsers

ParserLanguageFeatures
markedJavaScriptFast, lightweight
markdown-itJavaScriptPluggable, highly extensible
Python-MarkdownPythonFeature-rich, plugin system
kramdownRubySupports multiple output formats
PandocHaskellUniversal document converter

Rendering Engines

Client-side Rendering

Parse Markdown in the browser in real time:

javascript
// Using marked.js
const html = marked.parse('# Hello World');
document.body.innerHTML = html;

Advantages:

  • No server processing required
  • Real-time preview
  • Reduces server load

Disadvantages:

  • Depends on JavaScript
  • Not SEO-friendly
  • Slow initial load

Server-side Rendering

Pre-generate HTML on the server:

javascript
// Node.js example
const fs = require('fs');
const marked = require('marked');

const markdown = fs.readFileSync('document.md', 'utf8');
const html = marked.parse(markdown);

Advantages:

  • SEO-friendly
  • Fast loading
  • Does not depend on client-side JavaScript

Disadvantages:

  • Server processing overhead
  • Complex cache management

Static Site Generation

Pre-generate all pages at build time:

bash
# Using VitePress
npm run build

Advantages:

  • Fastest loading speed
  • Best SEO
  • High security
  • Easy deployment

Disadvantages:

  • Limited support for dynamic content
  • Longer build times

Extension Mechanisms

Plugin System

Many parsers support plugin extensions:

javascript
// markdown-it plugin example
const md = require('markdown-it')()
  .use(require('markdown-it-footnote'))
  .use(require('markdown-it-deflist'))
  .use(require('markdown-it-abbr'));

Custom Renderer

javascript
// Custom link renderer
const renderer = new marked.Renderer();
renderer.link = function(href, title, text) {
  return `<a href="${href}" target="_blank">${text}</a>`;
};

Performance Optimization

Caching Strategy

javascript
const cache = new Map();

function parseMarkdown(content) {
  const hash = generateHash(content);
  if (cache.has(hash)) {
    return cache.get(hash);
  }
  
  const result = marked.parse(content);
  cache.set(hash, result);
  return result;
}

Lazy Loading

javascript
// Only parse content in the visible area
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      parseAndRender(entry.target);
    }
  });
});

Streaming Processing

javascript
// Stream parsing for large files
const fs = require('fs');
const { Transform } = require('stream');

const markdownTransform = new Transform({
  transform(chunk, encoding, callback) {
    const html = marked.parse(chunk.toString());
    callback(null, html);
  }
});

fs.createReadStream('large-document.md')
  .pipe(markdownTransform)
  .pipe(fs.createWriteStream('output.html'));

Common Issues

1. Line Break Issues

Different parsers may handle line breaks differently:

markdown
Line 1
Line 2        ← These may be parsed as the same paragraph

Line 1  
Line 2        ← Two spaces at the end of the line force a line break

Line 1

Line 2        ← Blank line separates paragraphs

2. Mixing HTML

markdown
This is a mix of **Markdown** and <em>HTML</em>.

Pay attention to correct closing and nesting of HTML tags.

3. Special Character Escaping

markdown
You need to escape \* and \_ characters here.

Practical Application Scenarios

1. Blog Systems

Markdown articles → Static site generator → HTML website

2. Documentation Sites

.md documents → VitePress/Docusaurus → Online documentation

3. README Files

README.md → GitHub/GitLab → Project homepage

4. Note-taking Apps

Markdown notes → Real-time rendering → Rich text display

Next Steps

Now that you understand how Markdown works, you can:

Built by www.markdownlang.com