unified

Project: remarkjs/remark-contributors

Package: remark-contributors@6.0.2

  1. remark plugin to inject a given list of contributors into a table
  1. remark 213
  2. unified 180
  3. markdown 152
  4. plugin 136
  5. mdast 87
  6. remark-plugin 81
  7. contributors 2
  8. generation 2
  9. inject 2

remark-contributors

Build Coverage Downloads Size Sponsors Backers Chat

remark plugin to generate a list of contributors.

Contents

What is this?

This package is a unified (remark) plugin that takes a list of contributors and adds them in a table to a ## Contributors heading.

When should I use this?

This project is useful when you’re writing documentation for a project, typically a Node.js package, that has one or more readmes and maybe some other markdown files as well. You want to show who helped build the project by adding their names, websites, and perhaps some more info. This package is useful because it’s automated: you can customize who is added and how that’s formatted. But it won’t be as expressive as writing such sections manually.

This plugin is used in remark-git-contributors. The difference is that that plugin takes the Git history into account, which isn’t always needed or correct.

Install

This package is ESM only. In Node.js (version 16+), install with npm:

npm install remark-contributors

In Deno with esm.sh:

import remarkContributors from 'https://esm.sh/remark-contributors@7'

In browsers with esm.sh:

<script type="module">
  import remarkContributors from 'https://esm.sh/remark-contributors@7?bundle'
</script>

Use

Say we have the following file example.md in this project:

# Example

Some text.

## Contributors

## License

MIT

…and a module example.js:

import {remark} from 'remark'
import remarkContributors from 'remark-contributors'
import remarkGfm from 'remark-gfm'
import {read} from 'to-vfile'

const file = await remark()
  .use(remarkGfm) // This is needed to add support for tables (a GFM feature).
  .use(remarkContributors)
  .process(await read('example.md'))

console.log(String(file))

…then running node example.js yields:

# Example

Some text.

## Contributors

| Name                | Website                     |
| ------------------- | --------------------------- |
| **Hugh Kennedy**    | <https://hughsk.io>         |
| **Titus Wormer**    | <https://wooorm.com>        |
| **Vincent Weevers** | <https://vincentweevers.nl> |
| **Nick Baugh**      | <https://niftylettuce.com>  |

## License

MIT

👉 Note: These contributors are inferred from the package.json in this project. Running this example in a different package will yield different results.

API

This package exports no identifiers. The default export is remarkContributors.

unified().use(remarkContributors[, options])

Generate a list of contributors.

In short, this plugin:

Parameters
Returns

Transform (Transformer).

Notes

Contributor

Contributor in string form (name <email> (url)) or as object (TypeScript type).

Type
type Contributor = ContributorObject | string

ContributorObject

Contributor with fields (TypeScript type).

Type
type ContributorObject = Record<string, unknown>

Format

Format a field (TypeScript type).

Parameters
Returns

Content (Array<PhrasingContent> | PhrasingContent | string, optional)

Formatter

How to format a field, in short (TypeScript type).

The values can be:

Type
type Formatter = FormatterObject | boolean | string | null | undefined

FormatterObject

How to format a field (TypeScript type).

Fields

Formatters

Formatters for fields (TypeScript type).

Type
type Formatters = Record<string, Formatter>

Options

Configuration (TypeScript type).

Fields

Examples

Example: passing contributors

The following example shows how contributors can be passed:

import {remark} from 'remark'
import remarkContributors from 'remark-contributors'
import remarkGfm from 'remark-gfm'

const file = await remark()
  .use(remarkGfm)
  .use(remarkContributors, {
    contributors: [
      // String form:
      'Jane Doe <jane@doe.com> (https://example.com/jane)',
      // Object form, with just a name:
      {name: 'John Doe'},
      // Some more info:
      {name: 'Mona Lisa', url: 'https://github.com/monatheoctocat'}
    ]
  })
  .process('## Contributors')

console.log(String(file))

Yields:

## Contributors

| Name          | Website                             |
| ------------- | ----------------------------------- |
| **Jane Doe**  | <https://example.com/jane>          |
| **John Doe**  |                                     |
| **Mona Lisa** | <https://github.com/monatheoctocat> |

Example: formatters

By default, unknown fields in contributors will be added to the table:

import {remark} from 'remark'
import remarkContributors from 'remark-contributors'
import remarkGfm from 'remark-gfm'

const file = await remark()
  .use(remarkGfm)
  .use(remarkContributors, {
    contributors: [
      {name: 'Jane Doe', age: 31, topping: 'Mozzarella'},
      {name: 'John Doe', age: 29, topping: 'Olive'},
      {name: 'Mona Lisa', age: 3, topping: 'Pineapple'}
    ]
  })
  .process('## Contributors')

console.log(String(file))

Yields:

## Contributors

| Name          | age | topping    |
| ------------- | --- | ---------- |
| **Jane Doe**  | 31  | Mozzarella |
| **John Doe**  | 29  | Olive      |
| **Mona Lisa** | 3   | Pineapple  |

It’s possible to customize how these new fields are formatted:

@@ -12,7 +12,16 @@ const file = await remark()
       {name: 'Jane Doe', age: 31, topping: 'Mozzarella'},
       {name: 'John Doe', age: 29, topping: 'Olive'},
       {name: 'Mona Lisa', age: 3, topping: 'Pineapple'}
-    ]
+    ],
+    formatters: {
+      age: {
+        label: 'Age',
+        format(d) {
+          return {type: 'emphasis', children: [{type: 'text', value: String(d)}]}
+        }
+      },
+      topping: 'Topping'
+    }
   })
   .process('## Contributors')

Yields:

| Name          | Age  | Topping    |
| ------------- | ---- | ---------- |
| **Jane Doe**  | *31* | Mozzarella |
| **John Doe**  | *29* | Olive      |
| **Mona Lisa** | *3*  | Pineapple  |

👉 Note: observe that the labels of Age and Topping are now cased, and that the age values are now wrapped in emphasis.

Types

This package is fully typed with TypeScript. It exports the additional types Contributor, ContributorObject, Format, Formatter, FormatterObject, Formatters, and Options.

Compatibility

Projects maintained by the unified collective are compatible with maintained versions of Node.js.

When we cut a new major release, we drop support for unmaintained versions of Node. This means we try to keep the current release line, remark-contributors@^7, compatible with Node.js 16.

This plugin works with unified version 6+ and remark version 7+.

Security

options.contributors (or contributors in package.json) is used and injected into the tree when given or found. Data in those lists is formatted by options.formatters. If a user has access to either, this could open you up to a cross-site scripting (XSS) attack.

This may become a problem if the markdown is later transformed to rehype (hast) or opened in an unsafe markdown viewer.

Contribute

See contributing.md in remarkjs/.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.

Contributors

NameWebsite
Hugh Kennedyhttps://hughsk.io
Titus Wormerhttps://wooorm.com
Vincent Weevershttps://vincentweevers.nl
Nick Baughhttps://niftylettuce.com

License

MIT © Hugh Kennedy