{"id":13339443,"url":"https://github.com/syntax-tree/mdast-util-directive","last_synced_at":"2025-12-24T04:28:05.748Z","repository":{"id":46022584,"uuid":"306378959","full_name":"syntax-tree/mdast-util-directive","owner":"syntax-tree","description":"mdast extension to parse and serialize generic directives (`:cite[smith04]`)","archived":false,"fork":false,"pushed_at":"2025-01-22T14:54:35.000Z","size":130,"stargazers_count":17,"open_issues_count":0,"forks_count":6,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-02-23T21:19:42.679Z","etag":null,"topics":["container","directive","extension","generic","markdown","mdast","mdast-util","unist"],"latest_commit_sha":null,"homepage":"https://unifiedjs.com","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/syntax-tree.png","metadata":{"funding":{"github":"unifiedjs","open_collective":"unified"},"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"license","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-10-22T15:21:42.000Z","updated_at":"2025-02-10T14:10:43.000Z","dependencies_parsed_at":"2024-06-18T15:39:59.741Z","dependency_job_id":"e832bad8-5d1d-4e1d-9ba9-7e7a6a6ed4dc","html_url":"https://github.com/syntax-tree/mdast-util-directive","commit_stats":{"total_commits":72,"total_committers":4,"mean_commits":18.0,"dds":0.04166666666666663,"last_synced_commit":"5dd6e97d7fa3089f25a9af7b4ee382cc9dacdd9b"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/syntax-tree%2Fmdast-util-directive","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/syntax-tree%2Fmdast-util-directive/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/syntax-tree%2Fmdast-util-directive/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/syntax-tree%2Fmdast-util-directive/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/syntax-tree","download_url":"https://codeload.github.com/syntax-tree/mdast-util-directive/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243042736,"owners_count":20226695,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["container","directive","extension","generic","markdown","mdast","mdast-util","unist"],"created_at":"2024-07-29T19:20:03.325Z","updated_at":"2025-12-24T04:28:05.737Z","avatar_url":"https://github.com/syntax-tree.png","language":"JavaScript","readme":"# mdast-util-directive\n\n[![Build][badge-build-image]][badge-build-url]\n[![Coverage][badge-coverage-image]][badge-coverage-url]\n[![Downloads][badge-downloads-image]][badge-downloads-url]\n[![Size][badge-size-image]][badge-size-url]\n\n[mdast][github-mdast] extensions to parse and serialize\n[generic directives proposal][commonmark-directive-proposal]\n(`:cite[smith04]`,\n`::youtube[Video of a cat in a box]{v=01ab2cd3efg}`,\nand such).\n\n## Contents\n\n* [What is this?](#what-is-this)\n* [When to use this](#when-to-use-this)\n* [Install](#install)\n* [Use](#use)\n* [API](#api)\n  * [`directiveFromMarkdown()`](#directivefrommarkdown)\n  * [`directiveToMarkdown(options?)`](#directivetomarkdownoptions)\n  * [`ContainerDirective`](#containerdirective)\n  * [`Directives`](#directives)\n  * [`LeafDirective`](#leafdirective)\n  * [`TextDirective`](#textdirective)\n  * [`ToMarkdownOptions`](#tomarkdownoptions)\n* [HTML](#html)\n* [Syntax](#syntax)\n* [Syntax tree](#syntax-tree)\n  * [Nodes](#nodes)\n  * [Mixin](#mixin)\n* [Types](#types)\n* [Compatibility](#compatibility)\n* [Related](#related)\n* [Contribute](#contribute)\n* [License](#license)\n\n## What is this?\n\nThis package contains two extensions that add support for directive syntax in\nmarkdown to [mdast][github-mdast].\nThese extensions plug into\n[`mdast-util-from-markdown`][github-mdast-util-from-markdown]\n(to support parsing directives in markdown into a syntax tree)\nand\n[`mdast-util-to-markdown`][github-mdast-util-to-markdown]\n(to support serializing directives in syntax trees to markdown).\n\n## When to use this\n\nDirectives are one of the four ways to extend markdown:\nan arbitrary extension syntax\n(see [Extending markdown][github-micromark-extending] in micromark’s docs for\nthe alternatives and more info).\nThis mechanism works well when you control the content:\nwho authors it,\nwhat tools handle it,\nand where it’s displayed.\nWhen authors can read a guide on how to embed a tweet but are not expected to\nknow the ins and outs of HTML or JavaScript.\nDirectives don’t work well if you don’t know who authors content,\nwhat tools handle it,\nand where it ends up.\nExample use cases are a docs website for a project or product,\nor blogging tools and static site generators.\n\nYou can use these extensions when you are working with\n`mdast-util-from-markdown` and `mdast-util-to-markdown` already.\n\nWhen working with `mdast-util-from-markdown`,\nyou must combine this package with\n[`micromark-extension-directive`][github-micromark-extension-directive].\n\nWhen you don’t need a syntax tree,\nyou can use [`micromark`][github-micromark] directly with\n`micromark-extension-directive`.\n\nAll these packages are used [`remark-directive`][github-remark-directive],\nwhich focusses on making it easier to transform content by abstracting these\ninternals away.\n\nThis package only handles the syntax tree.\nFor example,\nit does not handle how markdown is turned to HTML.\nYou can use this with some more code to match your specific needs,\nto allow for anything from callouts,\ncitations,\nstyled blocks,\nforms,\nembeds,\nspoilers,\netc.\n[Traverse the tree][unifiedjs-tree-traversal] to change directives to whatever\nyou please.\n\n## Install\n\nThis package is [ESM only][github-gist-esm].\nIn Node.js (version 16+),\ninstall with [npm][npmjs-install]:\n\n```sh\nnpm install mdast-util-directive\n```\n\nIn Deno with [`esm.sh`][esmsh]:\n\n```js\nimport {directiveFromMarkdown, directiveToMarkdown} from 'https://esm.sh/mdast-util-directive@3'\n```\n\nIn browsers with [`esm.sh`][esmsh]:\n\n```html\n\u003cscript type=\"module\"\u003e\n  import {directiveFromMarkdown, directiveToMarkdown} from 'https://esm.sh/mdast-util-directive@3?bundle'\n\u003c/script\u003e\n```\n\n## Use\n\nSay our document `example.md` contains:\n\n```markdown\nA lovely language know as :abbr[HTML]{title=\"HyperText Markup Language\"}.\n```\n\n…and our module `example.js` looks as follows:\n\n```js\nimport fs from 'node:fs/promises'\nimport {fromMarkdown} from 'mdast-util-from-markdown'\nimport {toMarkdown} from 'mdast-util-to-markdown'\nimport {directive} from 'micromark-extension-directive'\nimport {directiveFromMarkdown, directiveToMarkdown} from 'mdast-util-directive'\n\nconst doc = await fs.readFile('example.md')\n\nconst tree = fromMarkdown(doc, {\n  extensions: [directive()],\n  mdastExtensions: [directiveFromMarkdown()]\n})\n\nconsole.log(tree)\n\nconst out = toMarkdown(tree, {extensions: [directiveToMarkdown()]})\n\nconsole.log(out)\n```\n\n…now running `node example.js` yields (positional info removed for brevity):\n\n```js\n{\n  type: 'root',\n  children: [\n    {\n      type: 'paragraph',\n      children: [\n        {type: 'text', value: 'A lovely language know as '},\n        {\n          type: 'textDirective',\n          name: 'abbr',\n          attributes: {title: 'HyperText Markup Language'},\n          children: [{type: 'text', value: 'HTML'}]\n        },\n        {type: 'text', value: '.'}\n      ]\n    }\n  ]\n}\n```\n\n```markdown\nA lovely language know as :abbr[HTML]{title=\"HyperText Markup Language\"}.\n```\n\n## API\n\nThis package exports the identifiers\n[`directiveFromMarkdown`][api-directive-from-markdown] and\n[`directiveToMarkdown`][api-directive-to-markdown].\nThere is no default export.\n\n### `directiveFromMarkdown()`\n\nCreate an extension for\n[`mdast-util-from-markdown`][github-mdast-util-from-markdown]\nto enable directives in markdown.\n\n###### Returns\n\nExtension for `mdast-util-from-markdown` to enable directives\n([`FromMarkdownExtension`][github-mdast-from-markdown-extension]).\n\n### `directiveToMarkdown(options?)`\n\nCreate an extension for\n[`mdast-util-to-markdown`][github-mdast-util-to-markdown]\nto enable directives in markdown.\n\n###### Parameters\n\n* `options`\n  ([`ToMarkdownOptions`][api-to-markdown-options], optional)\n  — configuration\n\n###### Returns\n\nExtension for `mdast-util-to-markdown` to enable directives\n([`ToMarkdownExtension`][github-mdast-to-markdown-extension]).\n\n### `ContainerDirective`\n\nDirective in flow content\n(such as in the root document or block quotes),\nwhich contains further flow content\n(TypeScript type).\n\n###### Type\n\n```ts\nimport type {BlockContent, DefinitionContent, Parent} from 'mdast'\n\ninterface ContainerDirective extends Parent {\n  type: 'containerDirective'\n  name: string\n  attributes?: Record\u003cstring, string | null | undefined\u003e | null | undefined\n  children: Array\u003cBlockContent | DefinitionContent\u003e\n}\n```\n\n### `Directives`\n\nThe different directive nodes\n(TypeScript type).\n\n###### Type\n\n```ts\ntype Directives = ContainerDirective | LeafDirective | TextDirective\n```\n\n### `LeafDirective`\n\nDirective in flow content\n(such as in the root document or block quotes),\nwhich contains nothing\n(TypeScript type).\n\n###### Type\n\n```ts\nimport type {PhrasingContent, Parent} from 'mdast'\n\ninterface LeafDirective extends Parent {\n  type: 'leafDirective'\n  name: string\n  attributes?: Record\u003cstring, string | null | undefined\u003e | null | undefined\n  children: Array\u003cPhrasingContent\u003e\n}\n```\n\n### `TextDirective`\n\nDirective in phrasing content\n(such as in paragraphs and headings)\n(TypeScript type).\n\n###### Type\n\n```ts\nimport type {PhrasingContent, Parent} from 'mdast'\n\ninterface TextDirective extends Parent {\n  type: 'textDirective'\n  name: string\n  attributes?: Record\u003cstring, string | null | undefined\u003e | null | undefined\n  children: Array\u003cPhrasingContent\u003e\n}\n```\n\n### `ToMarkdownOptions`\n\nConfiguration.\n\n###### Parameters\n\n* `collapseEmptyAttributes`\n  (`boolean`, default: `true`)\n  — collapse empty attributes: get `title` instead of `title=\"\"`\n* `preferShortcut`\n  (`boolean`, default: `true`)\n  — prefer `#` and `.` shortcuts for `id` and `class`\n* `preferUnquoted`\n  (`boolean`, default: `false`)\n  — leave attributes unquoted if that results in less bytes\n* `quoteSmart`\n  (`boolean`, default: `false`)\n  — use the other quote if that results in less bytes\n* `quote`\n  (`'\"'` or `\"'\"`,\n  default: the [`quote`][github-mdast-util-to-markdown-quote]\n  used by `mdast-util-to-markdown` for titles)\n  — preferred quote to use around attribute values\n\n## HTML\n\nThis utility does not handle how markdown is turned to HTML.\nYou can use this with some more code to match your specific needs,\nto allow for anything from callouts,\ncitations,\nstyled blocks,\nforms,\nembeds,\nspoilers,\netc.\n[Traverse the tree][unifiedjs-tree-traversal] to change directives to whatever\nyou please.\n\n## Syntax\n\nSee [Syntax in\n`micromark-extension-directive`][github-micromark-extension-directive-syntax].\n\n## Syntax tree\n\nThe following interfaces are added to **[mdast][github-mdast]** by this utility.\n\n### Nodes\n\n#### `TextDirective`\n\n```idl\ninterface TextDirective \u003c: Parent {\n  type: 'textDirective'\n  children: [PhrasingContent]\n}\n\nTextDirective includes Directive\n```\n\n**TextDirective** (**[Parent][github-mdast-parent]**) is a directive.\nIt can be used where **[phrasing][github-mdast-phrasing-content]** content is\nexpected.\nIts content model is also **[phrasing][github-mdast-phrasing-content]**\ncontent.\nIt includes the mixin **[Directive][syntax-tree-mixin-directive]**.\n\nFor example,\nthe following Markdown:\n\n```markdown\n:name[Label]{#x.y.z key=value}\n```\n\nYields:\n\n```js\n{\n  type: 'textDirective',\n  name: 'name',\n  attributes: {id: 'x', class: 'y z', key: 'value'},\n  children: [{type: 'text', value: 'Label'}]\n}\n```\n\n#### `LeafDirective`\n\n```idl\ninterface LeafDirective \u003c: Parent {\n  type: 'leafDirective'\n  children: [PhrasingContent]\n}\n\nLeafDirective includes Directive\n```\n\n**LeafDirective** (**[Parent][github-mdast-parent]**) is a directive.\nIt can be used where **[flow][github-mdast-flow-content]** content is expected.\nIts content model is **[phrasing][github-mdast-phrasing-content]** content.\nIt includes the mixin **[Directive][syntax-tree-mixin-directive]**.\n\nFor example,\nthe following Markdown:\n\n```markdown\n::youtube[Label]{v=123}\n```\n\nYields:\n\n```js\n{\n  type: 'leafDirective',\n  name: 'youtube',\n  attributes: {v: '123'},\n  children: [{type: 'text', value: 'Label'}]\n}\n```\n\n#### `ContainerDirective`\n\n```idl\ninterface ContainerDirective \u003c: Parent {\n  type: 'containerDirective'\n  children: [FlowContent]\n}\n\nContainerDirective includes Directive\n```\n\n**ContainerDirective** (**[Parent][github-mdast-parent]**) is a directive.\nIt can be used where **[flow][github-mdast-flow-content]** content is expected.\nIts content model is also **[flow][github-mdast-flow-content]** content.\nIt includes the mixin **[Directive][syntax-tree-mixin-directive]**.\n\nThe phrasing in the label is,\nwhen available,\nadded as a paragraph with a `directiveLabel: true` field,\nas the head of its content.\n\nFor example,\nthe following Markdown:\n\n```markdown\n:::spoiler[Open at your own peril]\nHe dies.\n:::\n```\n\nYields:\n\n```js\n{\n  type: 'containerDirective',\n  name: 'spoiler',\n  attributes: {},\n  children: [\n    {\n      type: 'paragraph',\n      data: {directiveLabel: true},\n      children: [{type: 'text', value: 'Open at your own peril'}]\n    },\n    {\n      type: 'paragraph',\n      children: [{type: 'text', value: 'He dies.'}]\n    }\n  ]\n}\n```\n\n### Mixin\n\n#### `Directive`\n\n```idl\ninterface mixin Directive {\n  name: string\n  attributes: Attributes?\n}\n\ninterface Attributes {}\ntypedef string AttributeName\ntypedef string AttributeValue\n```\n\n**Directive** represents something defined by an extension.\n\nThe `name` field must be present and represents an identifier of an extension.\n\nThe `attributes` field represents information associated with the node.\nThe value of the `attributes` field implements the **Attributes** interface.\n\nIn the **Attributes** interface,\nevery field must be an `AttributeName` and every value an `AttributeValue`.\nThe fields and values can be anything:\nthere are no semantics (such as by HTML or hast).\n\n\u003e In JSON,\n\u003e the value `null` must be treated as if the attribute was not included.\n\u003e In JavaScript,\n\u003e both `null` and `undefined` must be similarly ignored.\n\n## Types\n\nThis package is fully typed with [TypeScript][].\nIt exports the additional types [`ContainerDirective`][api-container-directive],\n[`Directives`][api-directives],\n[`LeafDirective`][api-leaf-directive],\nand\n[`TextDirective`][api-text-directive].\n\nIt also registers the node types with `@types/mdast`.\nIf you’re working with the syntax tree,\nmake sure to import this utility somewhere in your types,\nas that registers the new node types in the tree.\n\n```js\n/**\n * @import {} from 'mdast-util-directive'\n * @import {Root} from 'mdast'\n */\n\nimport {visit} from 'unist-util-visit'\n\n/** @type {Root} */\nconst tree = getMdastNodeSomeHow()\n\nvisit(tree, function (node) {\n  // `node` can now be one of the nodes for directives.\n})\n```\n\n## Compatibility\n\nProjects maintained by the unified collective are compatible with maintained\nversions of Node.js.\n\nWhen we cut a new major release,\nwe drop support for unmaintained versions of Node.\nThis means we try to keep the current release line,\n`mdast-util-directive@3`,\ncompatible with Node.js 16.\n\nThis utility works with `mdast-util-from-markdown` version 2+ and\n`mdast-util-to-markdown` version 2+.\n\n## Related\n\n* [`remark-directive`][github-remark-directive]\n  — remark plugin to support generic directives\n* [`micromark-extension-directive`][github-micromark-extension-directive]\n  — micromark extension to parse directives\n\n## Contribute\n\nSee [`contributing.md`][health-contributing]\nin\n[`syntax-tree/.github`][health]\nfor ways to get started.\nSee [`support.md`][health-support] for ways to get help.\n\nThis project has a [code of conduct][health-coc].\nBy interacting with this repository,\norganization,\nor community you agree to abide by its terms.\n\n## License\n\n[MIT][file-license] © [Titus Wormer][wooorm]\n\n\u003c!-- Definitions --\u003e\n\n[api-container-directive]: #containerdirective\n\n[api-directive-from-markdown]: #directivefrommarkdown\n\n[api-directive-to-markdown]: #directivetomarkdownoptions\n\n[api-directives]: #directives\n\n[api-leaf-directive]: #leafdirective\n\n[api-text-directive]: #textdirective\n\n[api-to-markdown-options]: #tomarkdownoptions\n\n[badge-build-image]: https://github.com/syntax-tree/mdast-util-directive/workflows/main/badge.svg\n\n[badge-build-url]: https://github.com/syntax-tree/mdast-util-directive/actions\n\n[badge-coverage-image]: https://img.shields.io/codecov/c/github/syntax-tree/mdast-util-directive.svg\n\n[badge-coverage-url]: https://codecov.io/github/syntax-tree/mdast-util-directive\n\n[badge-downloads-image]: https://img.shields.io/npm/dm/mdast-util-directive.svg\n\n[badge-downloads-url]: https://www.npmjs.com/package/mdast-util-directive\n\n[badge-size-image]: https://img.shields.io/bundlejs/size/mdast-util-directive\n\n[badge-size-url]: https://bundlejs.com/?q=mdast-util-directive\n\n[commonmark-directive-proposal]: https://talk.commonmark.org/t/generic-directives-plugins-syntax/444\n\n[esmsh]: https://esm.sh\n\n[file-license]: license\n\n[github-gist-esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c\n\n[github-mdast]: https://github.com/syntax-tree/mdast\n\n[github-mdast-flow-content]: https://github.com/syntax-tree/mdast#flowcontent\n\n[github-mdast-from-markdown-extension]: https://github.com/syntax-tree/mdast-util-from-markdown#extension\n\n[github-mdast-parent]: https://github.com/syntax-tree/mdast#parent\n\n[github-mdast-phrasing-content]: https://github.com/syntax-tree/mdast#phrasingcontent\n\n[github-mdast-to-markdown-extension]: https://github.com/syntax-tree/mdast-util-to-markdown#options\n\n[github-mdast-util-from-markdown]: https://github.com/syntax-tree/mdast-util-from-markdown\n\n[github-mdast-util-to-markdown]: https://github.com/syntax-tree/mdast-util-to-markdown\n\n[github-mdast-util-to-markdown-quote]: https://github.com/syntax-tree/mdast-util-to-markdown#optionsquote\n\n[github-micromark]: https://github.com/micromark/micromark\n\n[github-micromark-extending]: https://github.com/micromark/micromark#extending-markdown\n\n[github-micromark-extension-directive]: https://github.com/micromark/micromark-extension-directive\n\n[github-micromark-extension-directive-syntax]: https://github.com/micromark/micromark-extension-directive#syntax\n\n[github-remark-directive]: https://github.com/remarkjs/remark-directive\n\n[health]: https://github.com/syntax-tree/.github\n\n[health-coc]: https://github.com/syntax-tree/.github/blob/main/code-of-conduct.md\n\n[health-contributing]: https://github.com/syntax-tree/.github/blob/main/contributing.md\n\n[health-support]: https://github.com/syntax-tree/.github/blob/main/support.md\n\n[npmjs-install]: https://docs.npmjs.com/cli/install\n\n[syntax-tree-mixin-directive]: #directive\n\n[typescript]: https://www.typescriptlang.org\n\n[unifiedjs-tree-traversal]: https://unifiedjs.com/learn/recipe/tree-traversal/\n\n[wooorm]: https://wooorm.com\n","funding_links":["https://github.com/sponsors/unifiedjs","https://opencollective.com/unified"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsyntax-tree%2Fmdast-util-directive","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsyntax-tree%2Fmdast-util-directive","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsyntax-tree%2Fmdast-util-directive/lists"}