Relevant source files
The following files were used as context for generating this wiki page:
- packages/core/src/mdx-plugins/index.ts
- packages/obsidian/src/remark/index.ts
- packages/core/src/mdx-plugins/remark-llms.ts
- packages/mdx/src/loaders/mdx/remark-postprocess.ts
- packages/core/src/mdx-plugins/remark-structure.ts
- packages/core/src/content/mdx/preset-bundler.ts
- packages/core/src/mdx-plugins/rehype-toc.ts
- packages/preview/src/lib/md.ts
- packages/core/src/mdx-plugins/remark-steps.ts
- packages/doc-gen/src/remark-docgen.ts
- packages/mdx/src/rolldown/index.ts
- packages/core/src/content/mdx/preset-runtime.ts
- packages/obsidian/src/remark/remark-convert.ts
- packages/doc-gen/src/remark-install.ts
- packages/core/src/mdx-plugins/remark-mdx-files.ts
- packages/typescript/src/lib/remark-auto-type-table.ts
- packages/core/src/mdx-plugins/remark-directive-admonition.ts
- packages/obsidian/src/mdx/index.ts
- packages/core/src/mdx-plugins/remark-gfm.ts
- packages/core/src/mdx-plugins/remark-npm.ts
- packages/core/src/mdx-plugins/remark-heading.ts
- packages/core/src/mdx-plugins/remark-mdx-mermaid.ts
- packages/core/src/mdx-plugins/remark-code-tab.ts
- packages/mdx/src/config/preset.ts
- packages/local-md/src/md/compiler.ts
- packages/core/src/mdx-plugins/rehype-code.ts
- packages/content-collections/src/configuration.ts
- packages/core/src/mdx-plugins/remark-admonition.ts
- packages/mdx/src/loaders/mdx/remark-include.ts
- packages/core/src/content/md.ts
Overview
Fumadocs processes documentation through an extensible pipeline of remark and rehype plugins that transform abstract syntax trees to support features like admonitions, code tabs, and table of contents generation. These plugins integrate directly with MDX Loader Pipeline, Source Loader, and Content Collections Adapter to standardize markdown compilation across build tools and runtimes.
Sources: packages/core/src/mdx-plugins/index.ts:1-16, packages/core/src/content/mdx/preset-bundler.ts:23-92, packages/content-collections/src/configuration.ts:58-124
Admonition parsing and directive transformations
Directive-Based Admonition Containers
The remarkDirectiveAdmonition plugin processes containerDirective nodes within the MDX Loader Pipeline to support standard callout syntaxes, particularly for migrations from Docusaurus. It inspects tree nodes using unist-util-visit, checking whether a node name matches any entry in the configured types mapping. When a match is found, the plugin transforms the AST node into an mdxJsxFlowElement representing a callout container.
export function remarkDirectiveAdmonition({
tags: {
CalloutContainer = 'CalloutContainer',
CalloutTitle = 'CalloutTitle',
CalloutDescription = 'CalloutDescription',
} = {},
types = {
note: 'info',
tip: 'info',
info: 'info',
warn: 'warning',
warning: 'warning',
danger: 'error',
success: 'success',
},
}: RemarkDirectiveAdmonitionOptions = {}): Transformer<Root, Root> {Sources: packages/core/src/mdx-plugins/remark-directive-admonition.ts:29-44
The mapping between input directive names and target callout types defaults to specific standard identifiers.
| Directive Name | Target Callout Type |
|---|---|
note | info |
tip | info |
info | info |
warn | warning |
warning | warning |
danger | error |
success | success |
Sources: packages/core/src/mdx-plugins/remark-directive-admonition.ts:35-43
During transformation, any directive attributes present on the container are extracted into mdxJsxAttribute objects, alongside the primary type attribute. Children of the container are partitioned: paragraphs flagged with directiveLabel are routed into a title element named via CalloutTitle, while all remaining content blocks form the children of a description element named via CalloutDescription.
const titleNodes: PhrasingContent[] = [];
const descriptionNodes: (BlockContent | DefinitionContent)[] = [];
for (const item of node.children) {
if (item.type === 'paragraph' && item.data?.directiveLabel) {
titleNodes.push(...item.children);
} else {
descriptionNodes.push(item);
}
}
const children: MdxJsxFlowElement[] = [];
if (titleNodes.length > 0) {
children.push({
type: 'mdxJsxFlowElement',
name: CalloutTitle,
attributes: [],
children: titleNodes as BlockContent[],
});
}
if (descriptionNodes.length > 0) {
children.push({
type: 'mdxJsxFlowElement',
name: CalloutDescription,
attributes: [],
children: descriptionNodes,
});
}
Sources: packages/core/src/mdx-plugins/remark-directive-admonition.ts:65-95
Note
remarkDirectiveAdmonition requires remark-directive to be configured beforehand in the unified pipeline to parse container directive syntax correctly.
Sources: packages/core/src/mdx-plugins/remark-directive-admonition.ts:26-28
Legacy Admonition Syntax Rewriting
The legacy remarkAdmonition plugin provides backward compatibility for custom admonition tags (defaulting to :::) by scanning paragraph nodes, flattening their contents, and searching for matching type keys. While deprecated in favor of directive-based parsing, it maps alternative type names and extracts bracketed title meta strings into JSX attributes for standard Callout elements.
export function remarkAdmonition(options: RemarkAdmonitionOptions = {}): Transformer<Root, Root> {
const tag = options.tag ?? ':::';
// compatible with Docusaurus
const typeMap = options.typeMap ?? {
info: 'info',
warn: 'warn',
note: 'info',
tip: 'info',
warning: 'warn',
danger: 'error',
};
Sources: packages/core/src/mdx-plugins/remark-admonition.ts:22-34
Warning
Using nested admonitions with the legacy remarkAdmonition parser sets an hasIntercept flag that recursively invokes replaceNodes on inner child slices.
Sources: packages/core/src/mdx-plugins/remark-admonition.ts:40-41, packages/core/src/mdx-plugins/remark-admonition.ts:80|80
Heading slugs and table generation
Heading Slug Assignment and TOC Extraction
The remarkHeading plugin processes markdown trees using unist-util-visit to locate heading nodes and assign unique URL-safe identifiers via github-slugger. By default, it supports custom heading IDs through a regular expression that inspects the final text node of a heading for a bracketed slug pattern ([#slug]). When a custom ID is matched, the plugin assigns it to heading.data.hProperties.id and strips the trailing tag from the node value. If no custom ID is present, it flattens the node content and passes it to the configured slug function.
const regex = /\s*\[#(?<slug>[^]+?)]\s*$/;Sources: packages/core/src/mdx-plugins/remark-heading.ts:16-16, packages/core/src/mdx-plugins/remark-heading.ts:63-95
When generateToc is enabled, the plugin constructs an array of TOCItemType entries storing the title text, hash URL, and heading depth, attaching the resulting collection directly to file.data.toc.
if (generateToc) {
toc.push({
title: flattened ?? flattenNode(heading),
url: `#${props.id}`,
depth: heading.depth,
});
}Sources: packages/core/src/mdx-plugins/remark-heading.ts:86-92, packages/core/src/mdx-plugins/remark-heading.ts:97-97
Note
remarkHeading initializes a fresh Slugger instance and resets it on each transformer execution to guarantee deterministic ID generation across builds.
Sources: packages/core/src/mdx-plugins/remark-heading.ts:53-62
Structured Data Extraction
The remarkStructure plugin parses MDAST trees to build searchable structured data containing headings and content blocks. It scans nodes matching specified types, defaulting to paragraphs, blockquotes, table cells, headings, and leaf MDX flow elements.
export const remarkStructureDefaultOptions = {
types: ['heading', 'paragraph', 'blockquote', 'tableCell', 'mdxJsxFlowElement'],
mdxTypes(node) {
return !node.children || node.children.length === 0;
},
exportAs: false,
} satisfies StructureOptions;Sources: packages/core/src/mdx-plugins/remark-structure.ts:94-100
If a heading node lacks an hProperties.id, remarkStructure emits a warning and skips it, requiring remarkHeading to run beforehand in the pipeline.
if (typeof id !== 'string') {
console.warn(
'[remark-structure] hProperties.id is missing in heading node, it is required to generate heading data. You can add remark-heading prior to remark-structure to generate heading IDs.',
);
return 'skip';
}Sources: packages/core/src/mdx-plugins/remark-structure.ts:173-178
Collected blocks associate their content with the most recently encountered heading ID, storing the structured output in file.data.structuredData or serializing it as an MDX export when exportAs is configured.
file.data.structuredData = data;
if (exportAs) {
tree.children.unshift(
toMdxExport(typeof exportAs === 'string' ? exportAs : 'structuredData', data),
);
}Sources: packages/core/src/mdx-plugins/remark-structure.ts:204-209
Rehype Table of Contents Generation
The rehypeToc plugin inspects HTML element trees for heading tags (h1 through h6) to build a table of contents directly from HAST nodes. It recognizes control tags appended to heading text to alter behavior: [!toc] suppresses the heading from the table of contents and strips the tag, while [toc] includes the heading but removes the tag from the rendered output.
const TocOnlyTag = '[toc]';
const NoTocTag = '[!toc]';
const HeadingTags = new Set(['h1', 'h2', 'h3', 'h4', 'h5', 'h6']);Sources: packages/core/src/mdx-plugins/rehype-toc.ts:51-53, packages/core/src/mdx-plugins/rehype-toc.ts:77-91
| Configuration Property | Type | Default Value | Purpose |
|---|---|---|---|
exportToc | boolean | { as: 'data' } | { as: 'esm', name: string } | true | Determines whether the table of contents is exported as an ESM variable or stored in virtual file data. |
Sources: packages/core/src/mdx-plugins/rehype-toc.ts:8-30, packages/core/src/mdx-plugins/rehype-toc.ts:55-61
When exportToc is configured as an ESM export (defaulting to the name toc), the plugin converts HAST heading nodes into ESTree JSX fragments using hast-util-to-estree.
if (exportToc.as === 'esm') {
const esmItems: {
title: JSXElement;
url: string;
depth: number;
_step?: number;
}[] = [];
for (const item of items) {
const root = toEstree(item.title, {
elementAttributeNameCase: 'react',
stylePropertyNameCase: 'dom',
}).body[0];
if (root.type === 'ExpressionStatement' && root.expression.type === 'JSXElement') {
esmItems.push({
...item,
title: root.expression,
});
}Sources: packages/core/src/mdx-plugins/rehype-toc.ts:110-128
Warning
Headings without a valid string identifier in their properties are skipped by rehypeToc and omitted from the generated table of contents.
Sources: packages/core/src/mdx-plugins/rehype-toc.ts:73-74
Sequential step list conversion
Step Detection and Parsing
The remarkSteps plugin transforms consecutive step headings and their accompanying content into structured MDX JSX flow elements. It accepts an options object to customize CSS class names for both the outer steps container and individual step items.
| Configuration Property | Type | Default Value | Purpose |
|---|---|---|---|
steps | string | 'fd-steps' | Class name assigned to the outer wrapper container div element. |
step | string | 'fd-step' | Class name assigned to each individual step item container div element. |
Sources: packages/core/src/mdx-plugins/remark-steps.ts:7-21, packages/core/src/mdx-plugins/remark-steps.ts:29-32
To identify step headings, the plugin evaluates heading text against a regular expression pattern matching numeric prefixes like 1. Hello World, or checks for the trailing tag [step] via handleTag. When a valid step pattern matches, the plugin strips the marker from the text node and injects a data-fd-step property containing the incremental step index onto the heading's data properties.
const StepRegex = /^(\d+)\.\s(.+)$/;
const StepTag = '[step]';Sources: packages/core/src/mdx-plugins/remark-steps.ts:23-24, packages/core/src/mdx-plugins/remark-steps.ts:70-90, packages/core/src/mdx-plugins/remark-steps.ts:124-132
Warning
If a heading has a mismatched depth or fails step parsing while a sequence is actively collecting, the plugin immediately terminates the current step group via onEnd().
Sources: packages/core/src/mdx-plugins/remark-steps.ts:118-127
Code tabs and command generation
Package Manager Conversion and Tabs Generation
Fumadocs provides remark plugins to rewrite code blocks into multi-tab package manager interfaces. The core pipeline includes remarkNpm and remarkCodeTab, alongside legacy support from remarkInstall.
| Plugin Name | Target Language / Marker | Output Element |
|---|---|---|
remarkNpm | package-install, npm | CodeBlockTabs / custom triggers |
remarkInstall | package-install | Tabs, Tab |
remarkCodeTab | Code blocks with tab attribute | CodeBlockTabs or Tabs / Tab |
Sources: packages/core/src/mdx-plugins/remark-npm.ts:60-73, packages/doc-gen/src/remark-install.ts:60, packages/core/src/mdx-plugins/remark-code-tab.ts:255-259
The remarkNpm plugin visits code blocks in the Markdown AST and detects nodes where the language is package-install or npm. For package-install blocks, if the text does not start with npm or npx, it automatically prepends npm install. It then maps over configured package managers to translate commands and generate code block tabs.
export function remarkNpm({
persist = false,
packageManagers = [
{ command: (cmd) => cmd, name: 'npm' },
{ command: (cmd) => convertLines(cmd, 'pnpm'), name: 'pnpm' },
{ command: (cmd) => convertLines(cmd, 'yarn'), name: 'yarn' },
{ command: (cmd) => convertLines(cmd, 'bun'), name: 'bun' },
],
}: RemarkNpmOptions = {}): Transformer<Root, Root> {Sources: packages/core/src/mdx-plugins/remark-npm.ts:46-54
Note
remarkInstall from @fumadocs/doc-gen is deprecated in favor of remarkNpm from fumadocs-core/mdx-plugins, which serves as a drop-in replacement.
Sources: packages/doc-gen/src/remark-install.ts:45
Custom Code Tabs and Attribute Parsing
The remarkCodeTab plugin processes adjacent code blocks decorated with meta attributes like tab and tab-group. It supports two layout handlers defined in Types: CodeBlockTabs and Tabs.
| Option Property | Type | Default Value | Purpose |
|---|---|---|---|
Tabs | 'CodeBlockTabs' | 'Tabs' | 'CodeBlockTabs' | Determines the component name used for rendering grouped tab containers. |
parseMdx | boolean | false | Enables parsing of embedded MDX inside tab trigger values. |
Sources: packages/core/src/mdx-plugins/remark-code-tab.ts:11-21, packages/core/src/mdx-plugins/remark-code-tab.ts:206
During visitation, remarkCodeTab uses parseCodeBlockAttributes to extract tab and tab-group metadata from code block strings, assigns them to node data properties, and strips them from the raw meta string so syntax highlighters do not receive unknown flags.
for (; end < node.children.length; end++) {
const child = node.children[end];
if (child.type !== 'code' || !child.meta) {
close();
continue;
}
const meta = parseCodeBlockAttributes(child.meta, ['tab', 'tab-group']);
if (!meta.attributes.tab) {
close();
continue;
}
if (start === -1) start = end;
child.meta = meta.rest;
child.data ??= {};
child.data.tab = meta.attributes.tab;
if (meta.attributes['tab-group']) {
child.data.tabGroup = meta.attributes['tab-group'];
}
}Sources: packages/core/src/mdx-plugins/remark-code-tab.ts:248-268
Warning
When processing Tabs in simple mode with parseMdx enabled, the plugin checks whether the existing node attributes contain an items property before attempting to parse tab names as MDX.
Sources: packages/core/src/mdx-plugins/remark-code-tab.ts:220-224
Mermaid diagram code block conversion
Remark Transformer and AST Replacement
The remarkMdxMermaid plugin transforms fenced code blocks containing diagram specifications into dynamic MDX JSX flow elements. It exports an options interface that accepts a custom language identifier.
| Option Property | Type | Default Value | Purpose |
|---|---|---|---|
lang | string | 'mermaid' | Specifies the target code block language identifier to match during AST visitation. |
Sources: packages/core/src/mdx-plugins/remark-mdx-mermaid.ts:21-26
The plugin returns a unified transformer function that traverses the markdown abstract syntax tree using unist-util-visit. It targets nodes of type code, validates their positional indices and parent references, and compares their language property against the configured target language.
export function remarkMdxMermaid(options: RemarkMdxMermaidOptions = {}): Transformer<Root, Root> {
const { lang = 'mermaid' } = options;
return (tree) => {
visit(tree, 'code', (node, idx, parent) => {
if (node.lang !== lang || !node.value || typeof idx !== 'number' || !parent) return;
parent.children[idx] = toMDX(node.value);
});
};Sources: packages/core/src/mdx-plugins/remark-mdx-mermaid.ts:31-40
Caution
The visitor function skips code block nodes where idx is not a number or where parent is undefined, preventing out-of-bounds mutations on root or unattached AST nodes.
Sources: packages/core/src/mdx-plugins/remark-mdx-mermaid.ts:36
MDX JSX Node Generation
When a matching code block is identified, the plugin delegates conversion to the toMDX helper function. This function constructs an MdxJsxFlowElement node configured to render the <Mermaid /> component.
function toMDX(code: string): MdxJsxFlowElement {
return {
type: 'mdxJsxFlowElement',
name: 'Mermaid',
attributes: [
{
type: 'mdxJsxAttribute',
name: 'chart',
value: code.trim(),
},
],
children: [],
};
}Sources: packages/core/src/mdx-plugins/remark-mdx-mermaid.ts:6-19
Note
The source code inside the matched code block is trimmed via code.trim() before being assigned to the chart attribute of the generated JSX element, removing leading and trailing whitespace from the diagram definition.
Sources: packages/core/src/mdx-plugins/remark-mdx-mermaid.ts:14
LLM exports and postprocessing pipeline
Remark LLM Stringification and Placeholder Transformation
The remarkLLMs plugin processes markdown trees to generate clean plain-text representations and exportable string constants suitable for large language model ingestion. It accepts an options interface extending stringifier configurations with export name, heading identifier inclusion, element filtering, and placeholder conversion settings.
| Option Property | Type | Default Value | Purpose |
|---|---|---|---|
as | string | '_markdown' | Defines the variable name for the exported markdown string. |
headingIds | boolean | true | Appends explicit heading anchors ([#id]) to output headings when present. |
filterElement | StringifyOptions['filterElement'] | Custom function | Filters elements; excludes mdxjsEsm by default while retaining others. |
mdxAsPlaceholder | string[] | undefined | Target MDX component tag names to stringify as runtime placeholders. |
_data | boolean | false | Stores the generated markdown string inside file.data.markdown. |
Sources: packages/core/src/mdx-plugins/remark-llms.ts:9-55
The internal stringifier customizes node serialization by invoking placeholder for matching mdxJsxFlowElement and mdxJsxTextElement nodes listed in mdxAsPlaceholder.
stringify(node, parent, state, info, ctx) {
if (mdxAsPlaceholder) {
switch (node.type) {
case 'mdxJsxFlowElement':
case 'mdxJsxTextElement':
if (node.name && mdxAsPlaceholder.includes(node.name))
return placeholder(node, parent, state, info);
}
}
return rest.stringify?.(node, parent, state, info, ctx);
},Sources: packages/core/src/mdx-plugins/remark-llms.ts:80-91
Note
The placeholder helper extracts valid non-expression attributes, formats element phrasing children, and serializes the resulting payload into a null-delimited JSON string format conforming to PlaceholderData.
Sources: packages/core/src/mdx-plugins/remark-llms.ts:112-129
Postprocessing Pipeline and Frontmatter Extraction
The remarkPostprocess transformer orchestrates document metadata generation, reference extraction, and optional LLM string export. It inspects configuration options to determine which values to extract and export into the module AST.
| Option Property | Type | Default Value | Purpose |
|---|---|---|---|
_format | 'md' | 'mdx' | Required | Specifies the underlying document format. |
valueToExport | string[] | [] | Additional property keys from file.data to export as named variables. |
includeProcessedMarkdown | boolean | LLMsOptions | false | Enables remarkLLMs processing and exports the resulting string. |
extractLinkReferences | boolean | false | Collects link href values and exports them via extractedReferences. |
includeMDAST | boolean | { removePosition?: boolean } | false | Serializes and exports the document MDAST via _mdast. |
Sources: packages/mdx/src/loaders/mdx/remark-postprocess.ts:14-40
Warning
If frontmatter.title is missing, the postprocessor traverses the AST to find the first level-1 heading and flattens its text nodes to auto-populate the document title.
Sources: packages/mdx/src/loaders/mdx/remark-postprocess.ts:56-64
Exported declarations are injected into the AST by converting JavaScript values into estree nodes using valueToEstree, wrapped in an mdxjsEsm node via getMdastExport, and prepended to the tree's children array.
function getMdastExport(name: string, value: unknown): RootContent {
return {
type: 'mdxjsEsm',
value: '',
data: {
estree: {
type: 'Program',
sourceType: 'module',
body: [
{
type: 'ExportNamedDeclaration',
attributes: [],
specifiers: [],
source: null,
declaration: {
type: 'VariableDeclaration',
kind: 'let',
declarations: [
{
type: 'VariableDeclarator',
id: {
type: 'Identifier',
name,
},
init: valueToEstree(value),
},
],
},
},
],
},
},
};
}Sources: packages/mdx/src/loaders/mdx/remark-postprocess.ts:128-161
Plugin presets and runtime aggregation
Pipeline Composition and Resolution
Fumadocs provides unified configuration presets that compose default remark and rehype plugin pipelines across different build environments and runtimes. The core package exports bundler and runtime preset factories (mdxPreset) alongside an MDX configuration preset (applyMdxPreset) that handles environments such as bundler or runtime.
| Preset Function | Package | Environment Context | Default Output Format |
|---|---|---|---|
mdxPreset | fumadocs-core/content/mdx/preset-bundler | Bundler build tools (Next.js, Vite, Webpack) | Unmodified / default |
mdxPreset | fumadocs-core/content/mdx/preset-runtime | Local or runtime execution | function-body |
applyMdxPreset | fumadocs/config/preset | Configurable (bundler or runtime) | function-body (for runtime) |
Sources: packages/core/src/content/mdx/preset-bundler.ts:26-92, packages/core/src/content/mdx/preset-runtime.ts:23-83, packages/mdx/src/config/preset.ts:50-131
The plugin resolution layer accepts user-defined arrays or functions, conditionally appending default remark plugins like remarkGfm, remarkHeading, remarkImage, remarkCodeTab, remarkNpm, and remarkStructure, as well as rehype plugins like rehypeCode and rehypeToc.
const remarkPlugins = await resolvePlugins(
(v) => [
import('remark-gfm').then((mod) => mod.default),
remarkHeadingOptions !== false &&
import('@/mdx-plugins/remark-heading').then((mod) => [
mod.remarkHeading,
{
generateToc: false,
...remarkHeadingOptions,
},
]),
_include ?? false,
remarkImageOptions !== false &&
import('@/mdx-plugins/remark-image').then((mod) => [
mod.remarkImage,
{
...remarkImageOptions,
useImport: remarkImageOptions?.useImport ?? true,
},
]),
remarkCodeTabOptions !== false &&
import('@/mdx-plugins/remark-code-tab').then((mod) => [
mod.remarkCodeTab,
remarkCodeTabOptions,
]),
remarkNpmOptions !== false &&
import('@/mdx-plugins/remark-npm').then((mod) => [mod.remarkNpm, remarkNpmOptions]),
...v,
remarkStructureOptions !== false &&
import('@/mdx-plugins/remark-structure').then((mod) => [
mod.remarkStructure,
{
exportAs: 'structuredData',
...remarkStructureOptions,
} satisfies Plugins.StructureOptions,
]),
],
mdxOptions.remarkPlugins,
);
const rehypePlugins = await resolvePlugins(
(v) => [
rehypeCodeOptions !== false &&
import('@/mdx-plugins/rehype-code').then((mod) => [mod.rehypeCode, rehypeCodeOptions]),
...v,
import('@/mdx-plugins/rehype-toc').then((mod) => mod.rehypeToc),
],
mdxOptions.rehypePlugins,
);Sources: packages/core/src/content/mdx/preset-bundler.ts:38-86
Tip
Setting any preset option to false (such as remarkImageOptions: false or rehypeCodeOptions: false) explicitly disables that specific plugin from the unified pipeline.
Sources: packages/core/src/content/mdx/preset-bundler.ts:15-20, packages/core/src/content/mdx/preset-bundler.ts:41-73
Alternative Runtimes and Vault Compilers
For lightweight markdown rendering and preview components, createMarkdownCompiler and createMarkdownRenderer instantiate standalone unified processors using remark, remarkRehype, and user-supplied plugin lists without full MDX compilation baggage.
const processor = remark()
.use(remarkPlugins)
.use(remarkRehype, remarkRehypeOptions)
.use(rehypePlugins);Sources: packages/preview/src/lib/md.ts:37-40, packages/core/src/content/md.ts:35-38
Similarly, the Obsidian integration builds a localized unified processor combining vault-specific remark plugins (remarkWikilinks, remarkConvert, remarkObsidianComment, and remarkBlockId) to transform vault files into compatible AST structures.
export function getRemarkPlugins(storage: VaultStorage, resolver: VaultResolver): PluggableList {
return [
[remarkWikilinks, { resolver, storage }],
[remarkConvert, { resolver, storage }],
remarkObsidianComment,
remarkBlockId,
];Sources: packages/obsidian/src/remark/index.ts:9-15, packages/obsidian/src/mdx/index.ts:24-24
Related
On This Page
OverviewAdmonition parsing and directive transformationsDirective-Based Admonition ContainersLegacy Admonition Syntax RewritingHeading slugs and table generationHeading Slug Assignment and TOC ExtractionStructured Data ExtractionRehype Table of Contents GenerationSequential step list conversionStep Detection and ParsingCode tabs and command generationPackage Manager Conversion and Tabs GenerationCustom Code Tabs and Attribute ParsingMermaid diagram code block conversionRemark Transformer and AST ReplacementMDX JSX Node GenerationLLM exports and postprocessing pipelineRemark LLM Stringification and Placeholder TransformationPostprocessing Pipeline and Frontmatter ExtractionPlugin presets and runtime aggregationPipeline Composition and ResolutionAlternative Runtimes and Vault CompilersRelated