nuckty
RU
All sections →

Markdown extension

A Markdown extension adds Markdown constructs through env.markdown. It registers a directive handler or a remark plugin that transforms mdast before conversion to BEMJSON.

Directives

KindSyntax
Text:name[label]{attrs}
Leaf::name[label]{attrs}
Container:::name{attrs} … :::

Write the name without a space after the colons. For compatibility, the engine also normalizes a plain ::: gallery at the start of a line without attributes; this is not a general rule for all spaced directives.

An unknown directive falls back to plain content. Attributes are available as node.attributes; mdast children are node.children, typed as unknown[].

API and example

env.markdown.directive(name, handler) accepts a DirectiveHandler: (node: DirectiveNode, env: unknown) => { raw?: string; [key: string]: unknown } | null. The second argument is the bridge environment. Returning null enables normal content conversion.

The example deliberately reduces content to text; formatting and links are not retained. For richer content, implement an appropriate node transformation.

import type { NucktyEnv } from 'nuckty';

interface TextNode {
    type?: string;
    value?: string;
    children?: TextNode[];
}

function text(nodes: TextNode[]): string {
    return nodes.map((node) => node.type === 'text' || node.type === 'inlineCode'
        ? node.value ?? ''
        : text(node.children ?? [])).join('');
}

export function register(env: NucktyEnv): void {
    env.markdown.directive('callout', (node) => ({
        block: 'callout',
        mods: { type: node.attributes?.class ?? 'note' },
        content: text((node.children ?? []) as TextNode[]),
    }));
    env.markdown.directive('badge', (node) => ({
        block: 'badge',
        mods: { type: node.attributes?.type ?? 'new' },
        content: text((node.children ?? []) as TextNode[]),
    }));
}

Use :::callout{.warning} with a paragraph inside, or ::badge[1.2]{type=new}. Add callout and badge to the bemdecl and provide their templates and styles on the levels. Producing a node does not add its block to the declaration.

env.markdown.use(plugin) accepts a remark plugin for arbitrary mdast transforms. For example, video uses @[provider](id) links. Gallery and grid directives combine Markdown and block extensions in one package; implementations are listed in the catalog.