Core

Footnotes

Plugin for adding footnote references and definitions to your Comark documents.

The Footnotes plugin adds support for footnote references and definitions. References are rendered as superscript links, and definitions are collected into a numbered list at the end of the document with back-reference links.

No peer dependencies are required.

Basic Usage

With Vue

App.vue
<script setup lang="ts">
import { Comark } from '@comark/vue'
import footnotes from '@comark/vue/plugins/footnotes'

const markdown = `
Comark supports footnotes[^1] with back-references[^2].

[^1]: Footnotes are rendered as a list at the end of the document.
[^2]: Each footnote includes a back-reference link to return to the text.
`
</script>

<template>
  <Suspense>
    <Comark :plugins="[footnotes()]">{{ markdown }}</Comark>
  </Suspense>
</template>

With React

App.tsx
import { Comark } from '@comark/react'
import footnotes from '@comark/react/plugins/footnotes'

const markdown = `
Comark supports footnotes[^1] with back-references[^2].

[^1]: Footnotes are rendered as a list at the end of the document.
[^2]: Each footnote includes a back-reference link to return to the text.
`

function App() {
  return (
    <Comark plugins={[footnotes()]}>{markdown}</Comark>
  )
}

With Svelte

App.svelte
<script lang="ts">
  import { Comark } from '@comark/svelte'
  import footnotes from '@comark/svelte/plugins/footnotes'

  const markdown = `
Comark supports footnotes[^1] with back-references[^2].

[^1]: Footnotes are rendered as a list at the end of the document.
[^2]: Each footnote includes a back-reference link to return to the text.
`
</script>

<Comark {markdown} plugins={[footnotes()]} />

With Parse API

parse.ts
import { parse } from 'comark'
import footnotes from 'comark/plugins/footnotes'

const result = await parse('Hello[^1]\n\n[^1]: World', {
  plugins: [footnotes()]
})

Syntax

Footnote References

Use [^label] anywhere inline to insert a footnote reference:

The theory of relativity[^1] changed physics.

Einstein also contributed to quantum mechanics[^qm].

Labels can be numbers or text — they serve as identifiers and are replaced with sequential numbers in the output.

Footnote Definitions

Define footnotes with [^label]: content on its own line:

[^1]: Albert Einstein published special relativity in 1905.
[^qm]: See the photoelectric effect paper, also from 1905.

Definitions can appear anywhere in the document — they are removed from their original position and collected into the footnotes section.

Complete Example

# Research Notes

The standard model[^sm] describes three of the four fundamental forces.
Gravity remains described by general relativity[^gr].

Dark matter[^dm] accounts for approximately 27% of the universe.

[^sm]: The Standard Model of particle physics classifies all known elementary particles.
[^gr]: Einstein's general theory of relativity, published in 1915.
[^dm]: Dark matter is inferred from gravitational effects on visible matter.

Rendered Output

The plugin produces the following AST structure:

Inline references become superscript links:

["sup", { "class": "footnote-ref" },
  ["a", { "href": "#fn-1", "id": "fnref-1" }, "[1]"]
]

Footnotes section is appended to the end of the document:

["section", { "class": "footnotes" },
  ["hr", {}],
  ["h2", { "id": "footnotes" }, "Footnotes"],
  ["ol", { "class": "footnotes-list" },
    ["li", { "id": "fn-1" },
      "Definition text", " ",
      ["a", { "href": "#fnref-1", "class": "footnote-backref" }, ""]
    ]
  ]
]

Configuration

footnotes({
  label: 'Footnotes',  // Section heading text
  hr: true,             // Add <hr> before the section
  backRef: '',         // Back-reference symbol
})
OptionTypeDefaultDescription
labelstring'Footnotes'Heading text for the footnotes section
hrbooleantrueWhether to render a horizontal rule before the section
backRefstring'↩'Symbol used for the back-reference link

Custom Configuration

import footnotes from 'comark/plugins/footnotes'

// Use "References" heading, no horizontal rule, custom symbol
const plugin = footnotes({
  label: 'References',
  hr: false,
  backRef: '',
})

CSS Classes

The plugin adds CSS classes for styling:

ElementClassDescription
<sup>footnote-refWrapper around the inline reference link
<section>footnotesThe footnotes section container
<ol>footnotes-listThe ordered list of footnote definitions
<a>footnote-backrefThe back-reference link in each definition

Example Styles

.footnote-ref {
  font-size: 0.75em;
  vertical-align: super;
  line-height: 0;
}

.footnote-ref a {
  color: #2563eb;
  text-decoration: none;
}

.footnotes {
  margin-top: 2rem;
  font-size: 0.9em;
  color: #555;
}

.footnotes hr {
  border: none;
  border-top: 1px solid #ddd;
}

.footnotes-list li {
  margin-bottom: 0.4em;
}

.footnote-backref {
  color: #2563eb;
  text-decoration: none;
  margin-left: 0.25em;
}

Numbering

Footnotes are numbered in the order they are first referenced in the document, not the order they are defined:

Second definition referenced first[^b], then first[^a].

[^a]: This becomes footnote 2.
[^b]: This becomes footnote 1.

Referencing the same footnote multiple times reuses the same number.

Footnotes in Inline Formatting

Footnote references work inside bold, italic, and other inline formatting:

**Bold text with a footnote[^1]** and *italic with another[^2]*.

[^1]: Works inside bold.
[^2]: Works inside italic too.

Stringify (Markdown Rendering)

The plugin exports a Footnote conditional handler that converts the footnote AST back into standard markdown footnote syntax. This is useful when you want to render a ComarkTree back to markdown and preserve footnotes.

import { parse } from 'comark'
import { renderMarkdown } from 'comark/render'
import footnotes, { Footnote } from 'comark/plugins/footnotes'

const tree = await parse('Hello[^1]\n\n[^1]: World', {
  plugins: [footnotes()]
})

const md = await renderMarkdown(tree, {
  components: { footnotes: Footnote },
})
// Hello[^1]
//
// [^1]: World

Without Footnote, renderMarkdown would serialize the footnote HTML structure (sup, section, ol, etc.) as Comark component syntax instead of native footnote syntax.