How Markdown Here Converts Markdown to HTML: The Rendering Pipeline Explained

Markdown Here converts Markdown to HTML through a three-stage pipeline that captures user input, processes it through the marked parser with custom extensions for syntax highlighting and math, then injects styled HTML back into the email compose area.

The rendering pipeline in the adam-p/markdown-here repository is designed to keep heavy processing out of the content script while maintaining fast performance in browser extensions. This lightweight architecture enables seamless Markdown rendering directly within email clients like Gmail and Outlook.

Stage 1: Capture and Dispatch (Content Script Entry Point)

When a user invokes Markdown Here, the process begins in the browser extension's content script. The src/chrome/contentscript.js file extracts the selected text (or the entire textarea content) and dispatches the raw Markdown string to the core rendering engine.

The entry point function markdownHere() in src/common/markdown-here.js receives four critical arguments:

markdownHere(document, markdownRenderer, logger, renderComplete);

The markdownRenderer parameter acts as a thin wrapper around MarkdownRender.markdownRender(), which lives in src/common/markdown-render.js. This abstraction allows the content script to remain lightweight while delegating parsing work to the shared core library.

Stage 2: Core Rendering Engine (markdown-render.js)

The heart of the Markdown to HTML conversion resides in src/common/markdown-render.js. The markdownRender() method orchestrates the transformation using three specialized external libraries configured through the markedOptions object (defined at lines 75-96).

The Marked Parser with Custom Renderer

Markdown Here leverages the marked library (bundled in src/common/marked.js) as its primary parser. Unlike standard implementations, the extension creates a custom Renderer instance to inject additional functionality:

  • Header anchor links via sanitizeLinkForAnchor when the header-anchors-enabled preference is active
  • Automatic URL scheme addition for bare URLs lacking protocols
  • Optional math rendering through the mathify function when math-enabled is true

The core parsing call executes as follows:

var renderedMarkdown = marked(mdText, markedOptions);

Syntax Highlighting with highlight.js

Code blocks receive automatic syntax highlighting through highlight.js. The integration occurs via the highlight callback within markedOptions, which analyzes code language and applies the appropriate CSS classes. The langPrefix option specifically injects the hljs class into code blocks, ensuring compatibility with highlight.js themes.

Math Rendering and Header Anchors

For users requiring mathematical notation, the pipeline conditionally processes LaTeX expressions through the math rendering helper. Header anchors are simultaneously processed to generate permalink fragments, allowing recipients to navigate long email documents via clickable table-of-contents links.

Stage 3: Post-Processing and DOM Injection

After markdownRender() returns the HTML string, markdownHere() (lines 466-472 in src/common/markdown-here.js) performs final preparation before insertion:

  1. Container Wrapping – The HTML is wrapped in a <div class="mdh"> container to namespace the content
  2. Style Injection – The CSS stylesheet (generated from src/chrome/markdown.css and injected via mdh.css) is attached to ensure the preview matches the final email appearance
  3. Content Replacement – The content script's markdownRenderComplete() callback (defined at line 72 in src/chrome/contentscript.js) replaces the original textarea or compose field content with the rendered HTML

The final styled HTML is then handed back to the host client (Gmail, Outlook, etc.) and displayed as the email body. For fallback scenarios, jsHtmlToText (via htmlToText) extracts plain-text from the generated HTML.

Summary

Frequently Asked Questions

What parser does Markdown Here use for Markdown conversion?

Markdown Here uses the marked library, bundled in src/common/marked.js, as its primary parser. According to the adam-p/markdown-here source code, the extension instantiates a custom Renderer class to modify default behavior, adding features like header anchors and automatic URL scheme detection while maintaining standard GitHub Flavored Markdown (GFM) compatibility.

How does Markdown Here handle code syntax highlighting?

The pipeline integrates highlight.js through the markedOptions.highlight callback. When markdownRender() processes code blocks, it passes the code content to highlight.js, which returns syntax-colored HTML with the hljs CSS class prefix. This occurs during the marked(mdText, markedOptions) call in src/common/markdown-render.js.

Can Markdown Here render mathematical equations?

Yes, when the math-enabled preference is active, the rendering pipeline includes a mathify processing step within the custom marked Renderer. This step detects LaTeX syntax in the Markdown input and converts it to renderable mathematical notation before the final HTML generation completes.

Where is the rendering logic located in the source code?

The rendering logic is split across three primary files: src/chrome/contentscript.js handles initial text capture and final insertion; src/common/markdown-here.js contains the markdownHere() entry point that coordinates the pipeline; and src/common/markdown-render.js houses the MarkdownRender.markdownRender() method that executes the actual Markdown to HTML conversion using marked and highlight.js.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →