{"id":13783920,"url":"https://github.com/remarkjs/remark-gfm","last_synced_at":"2025-05-14T20:04:32.363Z","repository":{"id":37284415,"uuid":"301091528","full_name":"remarkjs/remark-gfm","owner":"remarkjs","description":"remark plugin to support GFM (autolink literals, footnotes, strikethrough, tables, tasklists)","archived":false,"fork":false,"pushed_at":"2023-09-18T10:52:11.000Z","size":124,"stargazers_count":633,"open_issues_count":0,"forks_count":22,"subscribers_count":10,"default_branch":"main","last_synced_at":"2024-05-22T08:44:17.779Z","etag":null,"topics":["autolink","gfm","github","remark","remark-plugin","strikethrough","table","tasklist"],"latest_commit_sha":null,"homepage":"https://remark.js.org","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/remarkjs.png","metadata":{"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},"funding":{"github":"unifiedjs","open_collective":"unified"}},"created_at":"2020-10-04T09:42:34.000Z","updated_at":"2024-05-20T03:43:48.000Z","dependencies_parsed_at":"2024-01-17T03:14:09.927Z","dependency_job_id":"93e3907e-c311-4636-aacc-36f7a09e7e7b","html_url":"https://github.com/remarkjs/remark-gfm","commit_stats":{"total_commits":39,"total_committers":2,"mean_commits":19.5,"dds":0.02564102564102566,"last_synced_commit":"82542ee281b8aa1e113578a4a254717d0120fcb7"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remarkjs%2Fremark-gfm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remarkjs%2Fremark-gfm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remarkjs%2Fremark-gfm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remarkjs%2Fremark-gfm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/remarkjs","download_url":"https://codeload.github.com/remarkjs/remark-gfm/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248741145,"owners_count":21154250,"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":["autolink","gfm","github","remark","remark-plugin","strikethrough","table","tasklist"],"created_at":"2024-08-03T19:00:33.059Z","updated_at":"2025-04-13T15:54:46.121Z","avatar_url":"https://github.com/remarkjs.png","language":"JavaScript","funding_links":["https://github.com/sponsors/unifiedjs","https://opencollective.com/unified"],"categories":["JavaScript","Plugins"],"sub_categories":[],"readme":"# remark-gfm\n\n[![Build][build-badge]][build]\n[![Coverage][coverage-badge]][coverage]\n[![Downloads][downloads-badge]][downloads]\n[![Size][size-badge]][size]\n[![Sponsors][sponsors-badge]][collective]\n[![Backers][backers-badge]][collective]\n[![Chat][chat-badge]][chat]\n\n**[remark][]** plugin to support [GFM][] (autolink literals, footnotes,\nstrikethrough, tables, tasklists).\n\n## Contents\n\n* [What is this?](#what-is-this)\n* [When should I use this?](#when-should-i-use-this)\n* [Install](#install)\n* [Use](#use)\n* [API](#api)\n  * [`unified().use(remarkGfm[, options])`](#unifieduseremarkgfm-options)\n  * [`Options`](#options)\n* [Examples](#examples)\n  * [Example: `singleTilde`](#example-singletilde)\n  * [Example: `stringLength`](#example-stringlength)\n* [Bugs](#bugs)\n* [Authoring](#authoring)\n* [HTML](#html)\n* [CSS](#css)\n* [Syntax](#syntax)\n* [Syntax tree](#syntax-tree)\n* [Types](#types)\n* [Compatibility](#compatibility)\n* [Security](#security)\n* [Related](#related)\n* [Contribute](#contribute)\n* [License](#license)\n\n## What is this?\n\nThis package is a [unified][] ([remark][]) plugin to enable the extensions to\nmarkdown that GitHub adds with GFM: autolink literals (`www.x.com`), footnotes\n(`[^1]`), strikethrough (`~~stuff~~`), tables (`| cell |…`), and tasklists\n(`* [x]`).\nYou can use this plugin to add support for parsing and serializing them.\nThese extensions by GitHub to CommonMark are called [GFM][] (GitHub Flavored\nMarkdown).\n\nThis plugin does not handle how markdown is turned to HTML.\nThat’s done by [`remark-rehype`][remark-rehype].\nIf your content is not in English and uses footnotes, you should configure that\nplugin.\nWhen generating HTML, you might also want to enable [`rehype-slug`][rehype-slug]\nto add `id`s on headings.\n\nA different plugin, [`remark-frontmatter`][remark-frontmatter], adds support for\nfrontmatter.\nGitHub supports YAML frontmatter for files in repos and Gists but they don’t\ntreat it as part of GFM.\n\nAnother plugin, [`remark-github`][remark-github], adds support for how markdown\nworks in relation to a certain GitHub repo in comments, issues, PRs, and\nreleases, by linking references to commits, issues, and users.\n\nYet another plugin, [`remark-breaks`][remark-breaks], turns soft line endings\n(enters) into hard breaks (`\u003cbr\u003e`s).\nGitHub does this in a few places (comments, issues, PRs, and releases).\n\n## When should I use this?\n\nThis project is useful when you want to support the same features that GitHub\ndoes in files in a repo, Gists, and several other places.\nUsers frequently believe that some of these extensions, specifically autolink\nliterals and tables, are part of normal markdown, so using `remark-gfm` will\nhelp match your implementation to their understanding of markdown.\nThere are several edge cases where GitHub’s implementation works in unexpected\nways or even different than described in their spec, so *writing* in GFM is not\nalways the best choice.\n\nIf you *just* want to turn markdown into HTML (with maybe a few extensions such\nas GFM), we recommend [`micromark`][micromark] with\n[`micromark-extension-gfm`][micromark-extension-gfm] instead.\nIf you don’t use plugins and want to access the syntax tree, you can use\n[`mdast-util-from-markdown`][mdast-util-from-markdown] with\n[`mdast-util-gfm`][mdast-util-gfm].\n\n## Install\n\nThis package is [ESM only][esm].\nIn Node.js (version 16+), install with [npm][]:\n\n```sh\nnpm install remark-gfm\n```\n\nIn Deno with [`esm.sh`][esmsh]:\n\n```js\nimport remarkGfm from 'https://esm.sh/remark-gfm@4'\n```\n\nIn browsers with [`esm.sh`][esmsh]:\n\n```html\n\u003cscript type=\"module\"\u003e\n  import remarkGfm from 'https://esm.sh/remark-gfm@4?bundle'\n\u003c/script\u003e\n```\n\n## Use\n\nSay our document `example.md` contains:\n\n```markdown\n# GFM\n\n## Autolink literals\n\nwww.example.com, https://example.com, and contact@example.com.\n\n## Footnote\n\nA note[^1]\n\n[^1]: Big note.\n\n## Strikethrough\n\n~one~ or ~~two~~ tildes.\n\n## Table\n\n| a | b  |  c |  d  |\n| - | :- | -: | :-: |\n\n## Tasklist\n\n* [ ] to do\n* [x] done\n```\n\n…and our module `example.js` contains:\n\n```js\nimport rehypeStringify from 'rehype-stringify'\nimport remarkGfm from 'remark-gfm'\nimport remarkParse from 'remark-parse'\nimport remarkRehype from 'remark-rehype'\nimport {read} from 'to-vfile'\nimport {unified} from 'unified'\n\nconst file = await unified()\n  .use(remarkParse)\n  .use(remarkGfm)\n  .use(remarkRehype)\n  .use(rehypeStringify)\n  .process(await read('example.md'))\n\nconsole.log(String(file))\n```\n\n…then running `node example.js` yields:\n\n```html\n\u003ch1\u003eGFM\u003c/h1\u003e\n\u003ch2\u003eAutolink literals\u003c/h2\u003e\n\u003cp\u003e\u003ca href=\"http://www.example.com\"\u003ewww.example.com\u003c/a\u003e, \u003ca href=\"https://example.com\"\u003ehttps://example.com\u003c/a\u003e, and \u003ca href=\"mailto:contact@example.com\"\u003econtact@example.com\u003c/a\u003e.\u003c/p\u003e\n\u003ch2\u003eFootnote\u003c/h2\u003e\n\u003cp\u003eA note\u003csup\u003e\u003ca href=\"#user-content-fn-1\" id=\"user-content-fnref-1\" data-footnote-ref aria-describedby=\"footnote-label\"\u003e1\u003c/a\u003e\u003c/sup\u003e\u003c/p\u003e\n\u003ch2\u003eStrikethrough\u003c/h2\u003e\n\u003cp\u003e\u003cdel\u003eone\u003c/del\u003e or \u003cdel\u003etwo\u003c/del\u003e tildes.\u003c/p\u003e\n\u003ch2\u003eTable\u003c/h2\u003e\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth\u003ea\u003c/th\u003e\n\u003cth align=\"left\"\u003eb\u003c/th\u003e\n\u003cth align=\"right\"\u003ec\u003c/th\u003e\n\u003cth align=\"center\"\u003ed\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003c/table\u003e\n\u003ch2\u003eTasklist\u003c/h2\u003e\n\u003cul class=\"contains-task-list\"\u003e\n\u003cli class=\"task-list-item\"\u003e\u003cinput type=\"checkbox\" disabled\u003e to do\u003c/li\u003e\n\u003cli class=\"task-list-item\"\u003e\u003cinput type=\"checkbox\" checked disabled\u003e done\u003c/li\u003e\n\u003c/ul\u003e\n\u003csection data-footnotes class=\"footnotes\"\u003e\u003ch2 class=\"sr-only\" id=\"footnote-label\"\u003eFootnotes\u003c/h2\u003e\n\u003col\u003e\n\u003cli id=\"user-content-fn-1\"\u003e\n\u003cp\u003eBig note. \u003ca href=\"#user-content-fnref-1\" data-footnote-backref class=\"data-footnote-backref\" aria-label=\"Back to content\"\u003e↩\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/section\u003e\n```\n\n## API\n\nThis package exports no identifiers.\nThe default export is [`remarkGfm`][api-remark-gfm].\n\n### `unified().use(remarkGfm[, options])`\n\nAdd support GFM (autolink literals, footnotes, strikethrough, tables,\ntasklists).\n\n###### Parameters\n\n* `options` ([`Options`][api-options], optional)\n  — configuration\n\n###### Returns\n\nNothing (`undefined`).\n\n### `Options`\n\nConfiguration (TypeScript type).\n\n###### Fields\n\n* `firstLineBlank` (`boolean`, default: `false`)\n  — serialize with a blank line for the first line of footnote definitions\n* `stringLength` (`((value: string) =\u003e number)`, default: `d =\u003e d.length`)\n  — detect the size of table cells, used when aligning cells\n* `singleTilde` (`boolean`, default: `true`)\n  — whether to support strikethrough with a single tilde;\n  single tildes work on github.com, but are technically prohibited by GFM;\n  you can always use 2 or more tildes for strikethrough\n* `tablePipeAlign` (`boolean`, default: `true`)\n  — whether to align table pipes\n* `tableCellPadding` (`boolean`, default: `true`)\n  — whether to add a space of padding between table pipes and cells\n\n## Examples\n\n### Example: `singleTilde`\n\nTo turn off support for parsing strikethrough with single tildes, pass\n`singleTilde: false`:\n\n```js\n// …\n\nconst file = await unified()\n  .use(remarkParse)\n  .use(remarkGfm, {singleTilde: false})\n  .use(remarkRehype)\n  .use(rehypeStringify)\n  .process('~one~ and ~~two~~')\n\nconsole.log(String(file))\n```\n\nYields:\n\n```html\n\u003cp\u003e~one~ and \u003cdel\u003etwo\u003c/del\u003e\u003c/p\u003e\n```\n\n### Example: `stringLength`\n\nIt’s possible to align tables based on the visual width of cells.\nFirst, let’s show the problem:\n\n```js\nimport {remark} from 'remark'\nimport remarkGfm from 'remark-gfm'\n\nconst input = `| Alpha | Bravo |\n| - | - |\n| 中文 | Charlie |\n| 👩‍❤️‍👩 | Delta |`\n\nconst file = await remark().use(remarkGfm).process(input)\n\nconsole.log(String(file))\n```\n\nThe above code shows how remark can be used to format markdown.\nThe output is as follows:\n\n```markdown\n| Alpha    | Bravo   |\n| -------- | ------- |\n| 中文       | Charlie |\n| 👩‍❤️‍👩 | Delta   |\n```\n\nTo improve the alignment of these full-width characters and emoji, pass a\n`stringLength` function that calculates the visual width of cells.\nOne such algorithm is [`string-width`][string-width].\nIt can be used like so:\n\n```diff\n@@ -1,5 +1,6 @@\n import {remark} from 'remark'\n import remarkGfm from 'remark-gfm'\n+import stringWidth from 'string-width'\n\n@@ -10,7 +11,7 @@ async function main() {\n | 👩‍❤️‍👩 | Delta |`\n\n-const file = await remark().use(remarkGfm).process(input)\n+const file = await remark()\n+  .use(remarkGfm, {stringLength: stringWidth})\n+  .process(input)\n\n   console.log(String(file))\n```\n\nThe output of our code with these changes is as follows:\n\n```markdown\n| Alpha | Bravo   |\n| ----- | ------- |\n| 中文  | Charlie |\n| 👩‍❤️‍👩    | Delta   |\n```\n\n## Bugs\n\nFor bugs present in GFM but not here, or other peculiarities that are\nsupported, see each corresponding readme:\n\n* [autolink literal](https://github.com/micromark/micromark-extension-gfm-autolink-literal#bugs)\n* [footnote](https://github.com/micromark/micromark-extension-gfm-footnote#bugs)\n* strikethrough: n/a\n* [table](https://github.com/micromark/micromark-extension-gfm-table#bugs)\n* tasklists: n/a\n\n## Authoring\n\nFor recommendations on how to author GFM, see each corresponding readme:\n\n* [autolink literal](https://github.com/micromark/micromark-extension-gfm-autolink-literal#authoring)\n* [footnote](https://github.com/micromark/micromark-extension-gfm-footnote#authoring)\n* [strikethrough](https://github.com/micromark/micromark-extension-gfm-strikethrough#authoring)\n* [table](https://github.com/micromark/micromark-extension-gfm-table#authoring)\n* [tasklists](https://github.com/micromark/micromark-extension-gfm-task-list-item#authoring)\n\n## HTML\n\nThis plugin does not handle how markdown is turned to HTML.\nSee [`remark-rehype`][remark-rehype] for how that happens and how to change it.\n\n## CSS\n\nFor info on how GitHub styles these features, see each corresponding readme:\n\n* [autolink literal](https://github.com/micromark/micromark-extension-gfm-autolink-literal#css)\n* [footnote](https://github.com/micromark/micromark-extension-gfm-footnote#css)\n* [strikethrough](https://github.com/micromark/micromark-extension-gfm-strikethrough#css)\n* [table](https://github.com/micromark/micromark-extension-gfm-table#css)\n* [tasklists](https://github.com/micromark/micromark-extension-gfm-task-list-item#css)\n\n## Syntax\n\nFor info on the syntax of these features, see each corresponding readme:\n\n* [autolink literal](https://github.com/micromark/micromark-extension-gfm-autolink-literal#syntax)\n* [footnote](https://github.com/micromark/micromark-extension-gfm-footnote#syntax)\n* [strikethrough](https://github.com/micromark/micromark-extension-gfm-strikethrough#syntax)\n* [table](https://github.com/micromark/micromark-extension-gfm-table#syntax)\n* [tasklists](https://github.com/micromark/micromark-extension-gfm-task-list-item#syntax)\n\n## Syntax tree\n\nFor info on the syntax tree of these features, see each corresponding readme:\n\n* [autolink literal](https://github.com/syntax-tree/mdast-util-gfm-autolink-literal#syntax-tree)\n* [footnote](https://github.com/syntax-tree/mdast-util-gfm-footnote#syntax-tree)\n* [strikethrough](https://github.com/syntax-tree/mdast-util-gfm-strikethrough#syntax-tree)\n* [table](https://github.com/syntax-tree/mdast-util-gfm-table#syntax-tree)\n* [tasklists](https://github.com/syntax-tree/mdast-util-gfm-task-list-item#syntax-tree)\n\n## Types\n\nThis package is fully typed with [TypeScript][].\nIt exports the additional type [`Options`][api-options].\n\nThe node types are supported in `@types/mdast` by default.\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, we drop support for unmaintained versions of\nNode.\nThis means we try to keep the current release line, `remark-gfm@^4`, compatible\nwith Node.js 16.\n\nThis plugin works with `remark-parse` version 11+ (`remark` version 15+).\nThe previous version (v3) worked with `remark-parse` version 10 (`remark`\nversion 14).\nBefore that, v2 worked with `remark-parse` version 9 (`remark` version 13).\nEarlier versions of `remark-parse` and `remark` had a `gfm` option that enabled\nthis functionality, which defaulted to true.\n\n## Security\n\nUse of `remark-gfm` does not involve **[rehype][]** ([hast][]) or user\ncontent so there are no openings for [cross-site scripting (XSS)][wiki-xss]\nattacks.\n\n## Related\n\n* [`remark-github`][remark-github]\n  — link references to commits, issues, PRs, and users\n* [`remark-breaks`][remark-breaks]\n  — support breaks without needing spaces or escapes (enters to `\u003cbr\u003e`)\n* [`remark-frontmatter`][remark-frontmatter]\n  — support frontmatter (YAML, TOML, and more)\n* [`remark-directive`](https://github.com/remarkjs/remark-directive)\n  — support directives\n* [`remark-math`](https://github.com/remarkjs/remark-math)\n  — support math\n* [`remark-mdx`](https://github.com/mdx-js/mdx/tree/main/packages/remark-mdx)\n  — support MDX (ESM, JSX, expressions)\n\n## Contribute\n\nSee [`contributing.md`][contributing] in [`remarkjs/.github`][health] for ways\nto get started.\nSee [`support.md`][support] for ways to get help.\n\nThis project has a [code of conduct][coc].\nBy interacting with this repository, organization, or community you agree to\nabide by its terms.\n\n## License\n\n[MIT][license] © [Titus Wormer][author]\n\n\u003c!-- Definitions --\u003e\n\n[api-options]: #options\n\n[api-remark-gfm]: #unifieduseremarkgfm-options\n\n[author]: https://wooorm.com\n\n[backers-badge]: https://opencollective.com/unified/backers/badge.svg\n\n[build]: https://github.com/remarkjs/remark-gfm/actions\n\n[build-badge]: https://github.com/remarkjs/remark-gfm/workflows/main/badge.svg\n\n[chat]: https://github.com/remarkjs/remark/discussions\n\n[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg\n\n[coc]: https://github.com/remarkjs/.github/blob/HEAD/code-of-conduct.md\n\n[collective]: https://opencollective.com/unified\n\n[contributing]: https://github.com/remarkjs/.github/blob/HEAD/contributing.md\n\n[coverage]: https://codecov.io/github/remarkjs/remark-gfm\n\n[coverage-badge]: https://img.shields.io/codecov/c/github/remarkjs/remark-gfm.svg\n\n[downloads]: https://www.npmjs.com/package/remark-gfm\n\n[downloads-badge]: https://img.shields.io/npm/dm/remark-gfm.svg\n\n[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c\n\n[esmsh]: https://esm.sh\n\n[gfm]: https://github.github.com/gfm/\n\n[hast]: https://github.com/syntax-tree/hast\n\n[health]: https://github.com/remarkjs/.github\n\n[license]: license\n\n[mdast-util-from-markdown]: https://github.com/syntax-tree/mdast-util-from-markdown\n\n[mdast-util-gfm]: https://github.com/syntax-tree/mdast-util-gfm\n\n[micromark]: https://github.com/micromark/micromark\n\n[micromark-extension-gfm]: https://github.com/micromark/micromark-extension-gfm\n\n[npm]: https://docs.npmjs.com/cli/install\n\n[rehype]: https://github.com/rehypejs/rehype\n\n[rehype-slug]: https://github.com/rehypejs/rehype-slug\n\n[remark]: https://github.com/remarkjs/remark\n\n[remark-breaks]: https://github.com/remarkjs/remark-breaks\n\n[remark-frontmatter]: https://github.com/remarkjs/remark-frontmatter\n\n[remark-github]: https://github.com/remarkjs/remark-github\n\n[remark-rehype]: https://github.com/remarkjs/remark-rehype\n\n[size]: https://bundlejs.com/?q=remark-gfm\n\n[size-badge]: https://img.shields.io/bundlejs/size/remark-gfm\n\n[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg\n\n[string-width]: https://github.com/sindresorhus/string-width\n\n[support]: https://github.com/remarkjs/.github/blob/HEAD/support.md\n\n[typescript]: https://www.typescriptlang.org\n\n[unified]: https://github.com/unifiedjs/unified\n\n[wiki-xss]: https://en.wikipedia.org/wiki/Cross-site_scripting\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fremarkjs%2Fremark-gfm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fremarkjs%2Fremark-gfm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fremarkjs%2Fremark-gfm/lists"}