unified

Project: syntax-tree/mdast-util-directive

Package: mdast-util-directive@1.0.1

  1. Dependencies: 5·Dependents: 2
  2. mdast extension to parse and serialize generic directives (:cite[smith04])
  1. markdown 142
  2. util 128
  3. utility 124
  4. unist 120
  5. mdast 89
  6. mdast-util 29
  7. markup 17
  8. extension 7
  9. container 3
  10. generic 2
  11. directive 2

mdast-util-directive

Build Coverage Downloads Size Sponsors Backers Chat

Extension for mdast-util-from-markdown and/or mdast-util-to-markdown to support the generic directives proposal (:cite[smith04], ::youtube[Video of a cat in a box]{v=01ab2cd3efg}, and such) in mdast. When parsing (from-markdown), must be combined with micromark-extension-directive.

See micromark-extension-directive for how the syntax works. This utility handles parsing and serializing. Traverse the tree to change them to whatever you please.

You probably shouldn’t use this package directly, but instead use remark-directive with remark

Install

npm:

npm install mdast-util-directive

Use

Say our script, example.js, looks as follows:

var fromMarkdown = require('mdast-util-from-markdown')
var toMarkdown = require('mdast-util-to-markdown')
var syntax = require('micromark-extension-directive')
var directive = require('mdast-util-directive')

var doc = 'A lovely language know as :abbr[HTML]{title="HyperText Markup Language"}.'

var tree = fromMarkdown(doc, {
  extensions: [syntax()],
  mdastExtensions: [directive.fromMarkdown]
})

console.log(tree)

var out = toMarkdown(tree, {extensions: [directive.toMarkdown]})

console.log(out)

Now, running node example yields (positional info removed for brevity):

{
  type: 'root',
  children: [
    {
      type: 'paragraph',
      children: [
        {type: 'text', value: 'A lovely language know as '},
        {
          type: 'textDirective',
          name: 'abbr',
          attributes: {title: 'HyperText Markup Language'},
          children: [{type: 'text', value: 'HTML'}]
        },
        {type: 'text', value: '.'}
      ]
    }
  ]
}
A lovely language know as :abbr[HTML]{title="HyperText Markup Language"}.

API

directive.fromMarkdown

directive.toMarkdown

Note: the separate extensions are also available at mdast-util-directive/from-markdown and mdast-util-directive/to-markdown.

Support the generic directives proposal. The exports are extensions, respectively for mdast-util-from-markdown and mdast-util-to-markdown.

There are no options, but passing options.quote to mdast-util-to-markdown is honored for attributes.

This utility handles parsing and serializing. Traverse the tree to change them to whatever you please.

Syntax tree

The following interfaces are added to mdast by this utility.

Nodes

TextDirective

interface TextDirective <: Parent {
  type: "textDirective"
  children: [PhrasingContent]
}

TextDirective includes Directive

TextDirective (Parent) is a directive. It can be used where phrasing content is expected. Its content model is also phrasing content. It includes the mixin Directive.

For example, the following Markdown:

:name[Label]{#x.y.z key=value}

Yields:

{
  type: 'textDirective',
  name: 'name',
  attributes: {id: 'x', class: 'y z', key: 'value'},
  children: [{type: 'text', value: 'Label'}]
}

LeafDirective

interface LeafDirective <: Parent {
  type: "leafDirective"
  children: [PhrasingContent]
}

LeafDirective includes Directive

LeafDirective (Parent) is a directive. It can be used where flow content is expected. Its content model is phrasing content. It includes the mixin Directive.

For example, the following Markdown:

::youtube[Label]{v=123}

Yields:

{
  type: 'leafDirective',
  name: 'youtube',
  attributes: {v: '123'},
  children: [{type: 'text', value: 'Label'}]
}

ContainerDirective

interface ContainerDirective <: Parent {
  type: "containerDirective"
  children: [FlowContent]
}

ContainerDirective includes Directive

ContainerDirective (Parent) is a directive. It can be used where flow content is expected. Its content model is also flow content. It includes the mixin Directive.

The phrasing in the label is, when available, added as a paragraph with a directiveLabel: true field, as the head of its content.

For example, the following Markdown:

:::spoiler[Open at your own peril]
He dies.
:::

Yields:

{
  type: 'containerDirective',
  name: 'spoiler',
  attributes: {},
  children: [
    {
      type: 'paragraph',
      data: {directiveLabel: true},
      children: [{type: 'text', value: 'Open at your own peril'}]
    },
    {
      type: 'paragraph',
      children: [{type: 'text', value: 'He dies.'}]
    }
  ]
}

Mixin

Directive

interface mixin Directive {
  name: string
  attributes: Attributes?
}

interface Attributes {}
typedef string AttributeName
typedef string AttributeValue

Directive represents something defined by an extension.

The name field must be present and represents an identifier of an extension.

The attributes field represents information associated with the node. The value of the attributes field implements the Attributes interface.

In the Attributes interface, every field must be an AttributeName and every value an AttributeValue. The fields and values can be anything: there are no semantics (such as by HTML or hast).

In JSON, the value null must be treated as if the attribute was not included. In JavaScript, both null and undefined must be similarly ignored.

Contribute

See contributing.md in syntax-tree/.github for ways to get started. See support.md for ways to get help.

This project has a code of conduct. By interacting with this repository, organization, or community you agree to abide by its terms.

License

MIT © Titus Wormer