mdast-util-footnote

mdast extension to parse and serialize footnotes

Usage no npm install needed!

<script type="module">
  import mdastUtilFootnote from 'https://cdn.skypack.dev/mdast-util-footnote';
</script>

README

mdast-util-footnote

Build Coverage Downloads Size Sponsors Backers Chat

Extension for mdast-util-from-markdown and/or mdast-util-to-markdown to support footnotes in mdast. When parsing (from-markdown), must be combined with micromark-extension-footnote.

When to use this

Use this if you’re dealing with the AST manually. It might be better to use remark-footnotes with remark, which includes this but provides a nicer interface and makes it easier to combine with hundreds of plugins.

Install

This package is ESM only: Node 12+ is needed to use it and it must be imported instead of required.

npm:

npm install mdast-util-footnote

Use

Say we have the following file, example.md:

Here is a footnote call,[^1] and another.[^longnote]

[^1]: Here is the footnote.

[^longnote]: Here’s one with multiple blocks.

    Subsequent paragraphs are indented to show that they
belong to the previous footnote.

        { some.code }

    The whole paragraph can be indented, or just the first
    line.  In this way, multi-paragraph footnotes work like
    multi-paragraph list items.

This paragraph won’t be part of the note, because it
isn’t indented.

Here is an inline note.^[Inlines notes are easier to write, since
you don’t have to pick an identifier and move down to type the
note.]

And our module, example.js, looks as follows:

import fs from 'node:fs'
import {fromMarkdown} from 'mdast-util-from-markdown'
import {toMarkdown} from 'mdast-util-to-markdown'
import {footnote} from 'micromark-extension-footnote'
import {footnoteFromMarkdown, footnoteToMarkdown} from 'mdast-util-footnote'

const doc = fs.readFileSync('example.md')

const tree = fromMarkdown(doc, {
  extensions: [footnote({inlineNotes: true})],
  mdastExtensions: [footnoteFromMarkdown]
})

console.log(tree)

const out = toMarkdown(tree, {extensions: [footnoteToMarkdown]})

console.log(out)

Now, running node example yields:

{
  type: 'root',
  children: [
    {
      type: 'paragraph',
      children: [
        {type: 'text', value: 'Here is a footnote call,'},
        {type: 'footnoteReference', identifier: '1', label: '1'},
        {type: 'text', value: ' and another.'},
        {type: 'footnoteReference', identifier: 'longnote', label: 'longnote'}
      ]
    },
    {
      type: 'footnoteDefinition',
      identifier: '1',
      label: '1',
      children: [
        {
          type: 'paragraph',
          children: [{type: 'text', value: 'Here is the footnote.'}]
        }
      ]
    },
    {
      type: 'footnoteDefinition',
      identifier: 'longnote',
      label: 'longnote',
      children: [
        {
          type: 'paragraph',
          children: [{type: 'text', value: 'Here’s one with multiple blocks.'}]
        },
        {
          type: 'paragraph',
          children: [
            {type: 'text', value: 'Subsequent paragraphs are indented to show that they\nbelong to the previous footnote.'}
          ]
        },
        {type: 'code', value: '{ some.code }'},
        {
          type: 'paragraph',
          children: [
            {type: 'text', value: 'The whole paragraph can be indented, or just the first\nline.  In this way, multi-paragraph footnotes work like\nmulti-paragraph list items.'}
          ]
        }
      ]
    },
    {
      type: 'paragraph',
      children: [
        {type: 'text', value: 'This paragraph won’t be part of the note, because it\nisn’t indented.'}
      ]
    },
    {
      type: 'paragraph',
      children: [
        {type: 'text', value: 'Here is an inline note.'},
        {
          type: 'footnote',
          children: [
            {type: 'text', value: 'Inlines notes are easier to write, since\nyou don’t have to pick an identifier and move down to type the\nnote.'}
          ]
        }
      ]
    }
  ]
}
Here is a footnote call,[^1] and another.[^longnote]

[^1]: Here is the footnote.

[^longnote]: Here’s one with multiple blocks.

    Subsequent paragraphs are indented to show that they
    belong to the previous footnote.

        { some.code }

    The whole paragraph can be indented, or just the first
    line.  In this way, multi-paragraph footnotes work like
    multi-paragraph list items.

This paragraph won’t be part of the note, because it
isn’t indented.

Here is an inline note.^[Inlines notes are easier to write, since
you don’t have to pick an identifier and move down to type the
note.]

API

This package exports the following identifier: footnoteFromMarkdown, footnoteToMarkdown. There is no default export.

footnoteFromMarkdown

footnoteToMarkdown

Support footnotes. These exports are extensions, respectively for mdast-util-from-markdown and mdast-util-to-markdown.

Related

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