A remark plugin that transforms markdown code blocks into HTML structures with enhanced metadata support. This plugin handles both individual code blocks with options and multi-variant code examples. It's the first stage in a processing pipeline, typically followed by transformHtmlCode for final rendering.
Use this plugin to enhance markdown code blocks with custom data attributes for highlighting, transformations, and other features. It also supports creating multi-variant code examples to show the same code in different languages, package managers, or configurations.
filename=test.ts, highlight=2-3)variant=name and variant-group=name syntaxclass="language-*" attributesimport { unified } from 'unified';
import remarkParse from 'remark-parse';
import transformMarkdownCode from '@mui/internal-docs-infra/pipeline/transformMarkdownCode';
const processor = unified().use(remarkParse).use(transformMarkdownCode);
// next.config.js
const withMDX = require('@next/mdx')({
options: {
remarkPlugins: [transformMarkdownCode],
rehypePlugins: [transformHtmlCode], // For final processing
},
});
module.exports = withMDX({
// your Next.js config
});
The simplest usage - transform single code blocks by adding options directly:
Basic Example:
```ts filename=greeting.ts
const greeting: string = 'Hello, world!';
console.log(greeting);
```
HTML Output:
<dl>
<dt><code>greeting.ts</code></dt>
<dd>
<pre><code class="language-typescript" data-filename="greeting.ts">const greeting: string = "Hello, world!";
console.log(greeting);</code></pre>
</dd>
</dl>
Multiple Options (without filename):
```javascript transform
function test() {
console.log('line 2');
console.log('line 3');
}
```
HTML Output:
<pre><code class="language-javascript" data-transform="true">function test() {
console.log('line 2');
console.log('line 3');
}</code></pre>
Individual code blocks with options are processed immediately and don't require grouping with other blocks.
Show the same task across different package managers. This style is ideal when the variant names are self-evident from the code content and don't need explicit labeling:
Markdown Input:
```bash variant=npm
npm install package
```
```bash variant=pnpm
pnpm install package
```
```bash variant=yarn
yarn add package
```
HTML Output:
<pre>
<code class="language-shell" data-variant="npm">npm install package</code>
<code class="language-shell" data-variant="pnpm">pnpm install package</code>
<code class="language-shell" data-variant="yarn">yarn add package</code>
</pre>
Add descriptive labels for each variant when the differences aren't obvious from the code alone. This is particularly useful for implementation approaches, configuration strategies, or conceptual differences:
Markdown Input:
Production Environment
```javascript variant-group=deployment
const config = {
apiUrl: process.env.PROD_API_URL,
cache: { ttl: 3600 },
logging: { level: 'error' },
};
```
Development Environment
```javascript variant-group=deployment
const config = {
apiUrl: 'http://localhost:3000',
cache: { ttl: 0 },
logging: { level: 'debug' },
};
```
Testing Environment
```javascript variant-group=deployment
const config = {
apiUrl: 'http://test-api.example.com',
cache: { ttl: 300 },
logging: { level: 'warn' },
};
```
HTML Output:
<pre>
<code class="language-javascript" data-variant="Production Environment">const config = {
apiUrl: process.env.PROD_API_URL,
cache: { ttl: 3600 },
logging: { level: 'error' }
};</code>
<code class="language-javascript" data-variant="Development Environment">const config = {
apiUrl: 'http://localhost:3000',
cache: { ttl: 0 },
logging: { level: 'debug' }
};</code>
<code class="language-javascript" data-variant="Testing Environment">const config = {
apiUrl: 'http://test-api.example.com',
cache: { ttl: 300 },
logging: { level: 'warn' }
};</code>
</pre>
Show examples across multiple programming languages:
Markdown Input:
```javascript variant=client
fetch('/api/data').then((res) => res.json());
```
```python variant=server
import requests
response = requests.get('/api/data')
```
```go variant=cli
resp, err := http.Get("/api/data")
```
HTML Output:
<pre>
<code class="language-javascript" data-variant="client">fetch('/api/data').then(res => res.json())</code>
<code class="language-python" data-variant="server">import requests
response = requests.get('/api/data')</code>
<code class="language-go" data-variant="cli">resp, err := http.Get("/api/data")</code>
</pre>
Add extra metadata using additional properties:
Markdown Input:
```bash variant=npm filename=install.sh
npm install package
```
```bash variant=pnpm filename=install.sh
pnpm install package
```
HTML Output:
<pre>
<code class="language-shell" data-variant="npm" data-filename="install.sh">npm install package</code>
<code class="language-shell" data-variant="pnpm" data-filename="install.sh">pnpm install package</code>
</pre>
Code blocks with options (but no variant or variant-group) are processed immediately:
<pre><code> element with data attributes (or <dl> structure if filename is provided)filename=test.ts → data-filename="test.ts")class="language-*" attributevariant= or variant-group=For variant-group format, paragraphs between code blocks become variant names:
Client-side
```js variant-group=implementation
fetch('/api/data');
```
Server-side
```js variant-group=implementation
const data = await db.query();
```
Creates variants named "Client-side" and "Server-side".
All markdown code block languages are supported:
js, javascript, ts, typescriptpython, go, rust, java, c, cppbash, shell, zsh, fishhtml, css, json, yaml, xmlThis plugin works seamlessly with transformHtmlCode:
Step 1 - Markdown:
npm
```bash variant-group=install
npm install package
```
pnpm
```bash variant-group=install
pnpm install package
```
Step 2 - After transformMarkdownCode:
<pre>
<code class="language-shell" data-variant="npm">npm install package</code>
<code class="language-shell" data-variant="pnpm">pnpm install package</code>
</pre>
Step 3 - After transformHtmlCode:
<pre data-precompute='{"npm":{"fileName":"index.sh","source":"npm install package"...}}'>
Error: expected pre tag to be handled by CodeHighlighter
</pre>
Add metadata to single code blocks for transformations, highlighting, or special processing.
Show installation instructions for different package managers.
Display the same functionality in React, Vue, Angular, etc.
Show different formats (JSON, YAML, TOML) for the same configuration.
Demonstrate requests in different programming languages or tools (curl, fetch, axios).
This plugin works out-of-the-box with no configuration required. It automatically:
Problem: Code blocks with options aren't getting transformed.
Solutions:
```js transform not ```jsvariant or variant-group (those trigger grouping behavior)Problem: Adjacent code blocks with variants aren't combining into a single <pre> element.
Solutions:
variant= or variant-group=)Problem: Using variant-group but variant names aren't extracted from paragraphs.
Solutions:
variant-group=samenameProblem: Generated HTML doesn't have class="language-*" attributes.
Solutions:
```javascript not just ```Generated HTML follows this pattern:
For code blocks without explicit filename:
<pre>
<code class="language-{lang}" data-variant="{name}" data-{prop}="{value}">
{escaped code content}
</code>
<!-- additional code elements for variants -->
</pre>
For code blocks with explicit filename:
<dl>
<dt><code>{filename}</code></dt>
<dd>
<pre>
<code class="language-{lang}" data-{prop}="{value}">
{escaped code content}
</code>
</pre>
</dd>
</dl>
data-variant: The variant name (from variant= or extracted label)class="language-*": The normalized language identifier (e.g., typescript not ts)data-*: Any additional properties from code block metadataThe plugin uses unist-util-visit to traverse the markdown AST and identify code blocks with metadata. It then:
mdxJsxFlowElement nodes with pre and code elementsdata-variant, className, and custom data attributesThe plugin handles language information in two ways:
- language isjavascript, meta is variant=npm`The parseMeta function splits metadata strings by spaces and parses key=value pairs:
transform - Boolean flag that becomes data-transform="true"highlight=2-3 - Becomes data-highlight="2-3"variant=name - Sets the variant for groupingvariant-group=name - Sets the variant group for label-based groupingfilename=package.json - Becomes data-filename="package.json"The plugin is designed to be robust and graceful:
Set data structures for efficient duplicate tracking