Warning
This is an internal project, and is not intended for public use. No support or stability guarantees are provided.
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 transformHtmlCodeBlock 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-type=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.mjs
import createMDX from '@next/mdx';
import transformMarkdownCode from '@mui/internal-docs-infra/pipeline/transformMarkdownCode';
import transformHtmlCodeBlock from '@mui/internal-docs-infra/pipeline/transformHtmlCodeBlock';
const withMDX = createMDX({
options: {
remarkPlugins: [transformMarkdownCode],
rehypePlugins: [transformHtmlCodeBlock], // For final processing
},
});
export default withMDX({
// your Next.js config
});
The plugin accepts a single option:
const processor = unified()
.use(remarkParse)
.use(transformMarkdownCode, { defaultInlineCodeLanguage: 'jsx' });
| Option | Type | Default | Description |
|---|---|---|---|
defaultInlineCodeLanguage | string | false | 'tsx' | Default language applied to inline code without an explicit {:lang} suffix. Set to false to disable default inline highlighting (explicit suffixes still apply). |
Code blocks need no configuration. The plugin automatically:
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:
Each variant becomes a <figure> (labeled by a <figcaption>) inside a shared <section>:
<section>
<figure>
<figcaption>npm variant</figcaption>
<dl>
<dd>
<pre><code class="language-shell" data-variant="npm">npm install package</code></pre>
</dd>
</dl>
</figure>
<figure>
<figcaption>pnpm variant</figcaption>
<dl>
<dd>
<pre><code class="language-shell" data-variant="pnpm">pnpm install package</code></pre>
</dd>
</dl>
</figure>
<figure>
<figcaption>yarn variant</figcaption>
<dl>
<dd>
<pre><code class="language-shell" data-variant="yarn">yarn add package</code></pre>
</dd>
</dl>
</figure>
</section>
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-type=deployment
const config = {
apiUrl: process.env.PROD_API_URL,
cache: { ttl: 3600 },
logging: { level: 'error' },
};
```
Development Environment
```javascript variant-type=deployment
const config = {
apiUrl: 'http://localhost:3000',
cache: { ttl: 0 },
logging: { level: 'debug' },
};
```
Testing Environment
```javascript variant-type=deployment
const config = {
apiUrl: 'http://test-api.example.com',
cache: { ttl: 300 },
logging: { level: 'warn' },
};
```
HTML Output:
<section>
<figure>
<figcaption>Production Environment variant</figcaption>
<dl>
<dd>
<pre><code class="language-javascript" data-variant="Production Environment">const config = { ... };</code></pre>
</dd>
</dl>
</figure>
<figure>
<figcaption>Development Environment variant</figcaption>
<dl>
<dd>
<pre><code class="language-javascript" data-variant="Development Environment">const config = { ... };</code></pre>
</dd>
</dl>
</figure>
<figure>
<figcaption>Testing Environment variant</figcaption>
<dl>
<dd>
<pre><code class="language-javascript" data-variant="Testing Environment">const config = { ... };</code></pre>
</dd>
</dl>
</figure>
</section>
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:
<section>
<figure>
<figcaption>client variant</figcaption>
<dl>
<dd>
<pre><code class="language-javascript" data-variant="client">fetch('/api/data').then((res) => res.json());</code></pre>
</dd>
</dl>
</figure>
<figure>
<figcaption>server variant</figcaption>
<dl>
<dd>
<pre><code class="language-python" data-variant="server">import requests
response = requests.get('/api/data')</code></pre>
</dd>
</dl>
</figure>
<figure>
<figcaption>cli variant</figcaption>
<dl>
<dd>
<pre><code class="language-go" data-variant="cli">resp, err := http.Get("/api/data")</code></pre>
</dd>
</dl>
</figure>
</section>
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:
A filename adds a <dt> entry inside each variant's <dl> (alongside the data-filename attribute):
<section>
<figure>
<figcaption>npm variant</figcaption>
<dl>
<dt><code>install.sh</code></dt>
<dd>
<pre><code
class="language-shell"
data-variant="npm"
data-filename="install.sh"
>npm install package</code></pre>
</dd>
</dl>
</figure>
<figure>
<figcaption>pnpm variant</figcaption>
<dl>
<dt><code>install.sh</code></dt>
<dd>
<pre><code
class="language-shell"
data-variant="pnpm"
data-filename="install.sh"
>pnpm install package</code></pre>
</dd>
</dl>
</figure>
</section>
Inline code spans are processed too. A {:lang} suffix sets the language explicitly, and inline code without a suffix is highlighted with the default language (tsx):
This is `<Component />{:jsx}` inline code — highlighted as JSX.
Use `<Component />` for rendering — highlighted with the default (`tsx`).
Select with `[data-active]{:css}` — highlighted as CSS.
The suffix is stripped from the rendered output and the <code> element receives the matching class="language-*" attribute. See Configuration to change or disable the default.
Code blocks with options (but no variant or variant-type) 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-type=For variant-type format, paragraphs between code blocks become variant names:
Client-side
```js variant-type=implementation
fetch('/api/data');
```
Server-side
```js variant-type=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 transformHtmlCodeBlock:
Step 1 - Markdown:
npm
```bash variant-type=install
npm install package
```
pnpm
```bash variant-type=install
pnpm install package
```
Step 2 - After transformMarkdownCode:
<section>
<figure>
<figcaption>npm variant</figcaption>
<dl>
<dd>
<pre><code class="language-shell" data-variant="npm">npm install package</code></pre>
</dd>
</dl>
</figure>
<figure>
<figcaption>pnpm variant</figcaption>
<dl>
<dd>
<pre><code class="language-shell" data-variant="pnpm">pnpm install package</code></pre>
</dd>
</dl>
</figure>
</section>
Step 3 - After transformHtmlCodeBlock:
<pre
data-precompute='{"npm":{"source":"npm install package","language":"shell",...},"pnpm":{"source":"pnpm install package","language":"shell",...}}'
>
Error: expected pre tag with precomputed data to be handled by the CodeHighlighter component</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).
Problem: Code blocks with options aren't getting transformed.
Solutions:
```js transform not ```jsvariant or variant-type (those trigger grouping behavior)Problem: Adjacent code blocks with variants aren't combining into a single <pre> element.
Solutions:
variant= or variant-type=)Problem: Using variant-type but variant names aren't extracted from paragraphs.
Solutions:
variant-type=samenameProblem: Generated HTML doesn't have class="language-*" attributes.
Solutions:
```javascript not just ```Generated HTML follows this pattern:
For individual code blocks without explicit filename:
<pre>
<code class="language-{lang}" data-{prop}="{value}">
{escaped code content}
</code>
</pre>
For variant groups (each variant in its own <figure>):
<section>
<figure>
<figcaption>{name} variant</figcaption>
<dl>
<!-- <dt><code>{filename}</code></dt> when a filename is provided -->
<dd>
<pre><code class="language-{lang}" data-variant="{name}" data-{prop}="{value}">
{escaped code content}
</code></pre>
</dd>
</dl>
</figure>
<!-- additional figures for the other variants -->
</section>
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:
element nodes (with hName/hProperties bridge data) for the pre and code elementsdata-variant, className, and custom data attributesremark-rehype passes throughThe 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-type=name - Sets the variant group for label-based groupingfilename=package.json - Becomes data-filename="package.json"collapseToEmpty / initialExpanded - Display flags forwarded as data-collapse-to-empty / data-initial-expanded (consumed by CodeHighlighter); collapseToEmpty=false opts a block out of a collapse-to-empty defaultdata-* attributes)The plugin is designed to be robust and graceful:
element nodes that integrate seamlessly with the rehype pipelineSet data structures for efficient duplicate trackingtype default = Plugin<[TransformMarkdownCodeOptions | undefined]>type TransformMarkdownCodeOptions = {
/**
* Default language to apply to inline code that doesn't have an explicit `{:lang}` suffix.
* Set to `false` to disable default highlighting for inline code.
* @default 'tsx'
*/
defaultInlineCodeLanguage?: string | false;
}transformHtmlCodeBlock - The rehype plugin that processes this plugin's output into precomputed datatransformMarkdownMetaLinks - Companion remark plugin that cleans up demo meta linkswithDocsInfra - Includes this plugin in its default MDX setup (and forwards defaultInlineCodeLanguage)