micromark-extension-directive

A micromark extension that adds generic directive syntax (:name[label]{attrs}) for building custom Markdown constructs.

Library
npm
v4.0.0
39stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
30/100Needs Attention
Development Activity0
Maintenance32
Community16
Maturity60
Momentum12

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
78/100Good
Architecture82
Code Quality88
Innovation68
Learning Curve75

micromark-extension-directive brings the generic directive proposal to micromark, giving Markdown a single, consistent way to express an open-ended set of custom constructs. Instead of inventing bespoke syntax for every new feature — callouts, embeds, abbreviations, spoilers — authors write :name[label]{attributes} for inline text directives, ::name[label]{attributes} for leaf (single-line block) directives, and :::name fenced blocks for container directives that can hold arbitrary nested content.

The package exports two extensions: directive(), which teaches micromark’s tokenizer to recognize the three directive forms, and directiveHtml(options), which lets consumers register per-directive handlers to control how each directive serializes to HTML (with a '*' fallback handler for anything unhandled). Unhandled directives simply emit nothing, so unknown directives fail safe rather than corrupting output.

It is a low-level building block in the unified/remark ecosystem: most users reach it indirectly through remark-directive, which wraps this package plus mdast-util-directive to produce a full AST-based directive-processing pipeline, but projects that already work directly with micromark’s tokenizer/compiler can depend on it standalone.

What You Get

  • A directive() syntax extension that adds tokenizer support for :name, ::name, and :::name directive forms to micromark
  • A directiveHtml(options) extension for controlling how each named directive is rendered to HTML, with a '*' catch-all handler
  • Full TypeScript types (Directive, Handle, HtmlOptions) shipped alongside the runtime code
  • CommonMark-strict parsing rules for directive syntax (no stray whitespace, matching fence lengths, no embedded line endings in labels/attributes)
  • Support for shorthand attribute syntax — {#id} and {.class} — alongside standard key=value HTML-style attributes
  • A production/development conditional export split, so instrumented development builds are opt-in via --conditions development

Common Use Cases

  • Implementing custom Markdown callouts, admonitions, or alert boxes (e.g. :::warning) in a static site generator or docs pipeline
  • Embedding third-party content like YouTube videos or tweets via leaf directives (e.g. ::youtube[Caption]{vid=...})
  • Adding inline semantic markup such as abbreviations or citations (e.g. :abbr[HTML]{title="..."}, :cite[smith04])
  • Building a foundation for remark-directive or other AST-level directive plugins that need the underlying micromark tokenizer support
  • Rendering spoiler/collapsible sections in Markdown-authored content (e.g. :::spoiler)

Under The Hood

Architecture The package is a thin, focused micromark extension split into three parallel tokenizer modules — directive-text.js, directive-leaf.js, and directive-container.js — each registered against the : character in syntax.js’s exported directive() function, one for micromark’s text construct map and two for its flow construct map. Each tokenizer module implements micromark’s character-code state-machine convention (a series of chained functions receiving and returning tokenizer effects), factored further into shared factory-name.js, factory-label.js, and factory-attributes.js helpers so the three directive forms don’t duplicate the label/attribute-parsing logic. A separate html.js module implements the compiler side as a stateless set of enter/exit handler maps keyed by token name, buffering content between an opening and closing token and using parse-entities to decode HTML entities in attribute values. Nothing in the core module depends on the wider unified/remark AST layer — this is pure micromark-level tokenizing and compiling, which is what lets higher-level packages like mdast-util-directive build a syntax tree on top without re-parsing.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search