{"id":17239041,"url":"https://github.com/binarymuse/node-cmark-gfm","last_synced_at":"2025-04-14T02:31:55.411Z","repository":{"id":11606795,"uuid":"70100243","full_name":"BinaryMuse/node-cmark-gfm","owner":"BinaryMuse","description":"Node.js bindings to GitHub's GFM-enhanced fork of cmark, the CommonMark reference implementation in C","archived":false,"fork":false,"pushed_at":"2023-03-06T05:57:43.000Z","size":1052,"stargazers_count":9,"open_issues_count":10,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-13T13:49:45.083Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/cmark-gfm","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/BinaryMuse.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-10-05T21:17:45.000Z","updated_at":"2022-05-07T12:52:48.000Z","dependencies_parsed_at":"2024-06-18T18:33:27.691Z","dependency_job_id":"9420b54f-24e2-407c-a431-bf4e586680cf","html_url":"https://github.com/BinaryMuse/node-cmark-gfm","commit_stats":{"total_commits":285,"total_committers":5,"mean_commits":57.0,"dds":0.5298245614035088,"last_synced_commit":"6e2300fb7b7a2e2d47251381e1078440d435859d"},"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BinaryMuse%2Fnode-cmark-gfm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BinaryMuse%2Fnode-cmark-gfm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BinaryMuse%2Fnode-cmark-gfm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BinaryMuse%2Fnode-cmark-gfm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BinaryMuse","download_url":"https://codeload.github.com/BinaryMuse/node-cmark-gfm/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248810888,"owners_count":21165196,"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":[],"created_at":"2024-10-15T05:47:34.527Z","updated_at":"2025-04-14T02:31:54.714Z","avatar_url":"https://github.com/BinaryMuse.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# cmark-gfm\n\ncmark-gfm is a Node.js wrapper around [libcmark-gfm](https://github.com/github/cmark-gfm), GitHub's [GFM-enhanced](https://github.github.com/gfm/) fork of [cmark](https://github.com/commonmark/cmark), the reference implementation of [CommonMark](http://commonmark.org/) in C by John MacFarlane.\n\n## Installation\n\ncmark-gfm is distributed via the npm registry, and can be installed with `npm` and similar tools:\n\n```\nnpm install cmark-gfm\n```\n\n## API\n\n**`renderHtml(markdown[, options][, callback])`**\n\nConverts a Markdown string to HTML asynchronously. If you do not provide a `callback`, `renderHtml` will return a `Promise` that will resolve to the resulting HTML. If `options` is omitted, default options will be used.\n\n  * `markdown` - a string of Markdown to convert to HTML\n  * `options` - a hash of options (see *Options*, below)\n  * `callback` - a Node.js-style callback to call with the resulting HTML once the Markdown has been rendered\n    * `error` - any error that occurred\n    * `html` - the resulting HTML\n\nExample:\n\n```javascript\nconst cmark = require('cmark-gfm')\n\nconst options = { ... }\n\n// Promise-style\ncmark.renderHtml('# Hello there!', options)\n  .then(html =\u003e console.log(html))\n  .catch(error =\u003e console.error(error))\n\n// Callback-style\ncmark.renderHtml('# Hello there!', options, (error, html) =\u003e {\n  if (error) {\n    console.error(error)\n    return\n  }\n\n  console.log(html)\n})\n```\n\n**`html = renderHtmlSync(markdown[, options])`**\n\nConverts a Markdown string to HTML synchronously. If `options` is omitted, default options will be used.\n\n  * `markdown` - a string of Markdown to convert to HTML\n  * `options` - a hash of options (see *Options*, below)\n\nExample:\n\n```javascript\nconst cmark = require('cmark-gfm')\n\nconst options = { ... }\n\ntry {\n  const html = cmark.renderHtmlSync('# Hello there!', options)\n  console.log(html)\n} catch (error) {\n  console.error(error)\n}\n```\n\n**`createStreamingParser([options])`**\n\nCreates a [stream](https://nodejs.org/api/stream.html) with a writable end that accepts Markdown and a readable end that produces HTML. The parser ingests Markdown and converts it to HTML asynchronously. If `options` is omitted, default options will be used.\n\n  * `options` - a hash of options (see *Options*, below)\n\nExample:\n\n```javascript\nconst cmark = require('cmark-gfm')\nconst fs = require('fs')\n\nconst options = { ... }\n\nfs.createReadStream('./input.md')\n  .pipe(cmark.createStreamingParser(options))\n  .pipe(fs.createWriteStream('./output.html'))\n```\n\n### Options\n\ncmark-gfm supports a variety of options that it passes to the underlying libcmark-gfm library. You can enable most options by setting its name to the value of `true` in your `options` object; to enable an extension, add its name as a key to an `extensions` object with a value of `true`. For example, to enable the `smart` and `footnotes` options and the `strikethrough` extension:\n\n```javascript\nconst cmark = require('cmark-gfm')\n\nconst options = {\n  smart: true,\n  footnotes: true,\n  extensions: {\n    strikethrough: true\n  }\n}\n\ncmark.renderHtml(markdown, options)\n  .then(/* ... */)\n```\n\nYou can find a summary of all the options in the table below, as well as additional information for some options in the *Features* section later in this document.\n\n| Name | Type | Description\n|---|---|---|\n| `sourcepos`* | `bool` | Adds a `data-sourcepos` attribute to elements that indicate the range of Markdown that resulted in the element |\n| `hardbreaks`* | `bool` | Renders softbreak elements as hard line breaks |\n| `nobreaks`* | `bool` | Renders softbreak elements as spaces |\n| `validateUtf8` | `bool` | Replaces illegal UTF-8 sequences with `U+FFFD` |\n| `smart` | `bool` | Replaces straight quotes with curly ones, and turns `---` into em dashes and `--` into en dashes |\n| `githubPreLang`* | `bool` | Uses GitHub style `\u003cpre lang=\"x\"\u003e` tags for code blocks |\n| `liberalHtmltag` | `bool` | Allows HTML tags to be parsed as HTML even if they are not well formed (e.g. `\u003c div\u003e` instead of just `\u003cdiv\u003e`) |\n| `footnotes`* | `bool` | Enables footnote parsing and rendering |\n| `strikethroughDoubleTilde` | `bool` | When enabled, the `strikethrough` extension will only render text as strikethrough if it is surrounded by exactly `~~two tildes~~` |\n| `fullInfoString`* | `bool` | Adds additional code block info as an additional attribute on the resulting HTML element |\n| `unsafe`* | `bool` | Allows raw HTML and unsafe links (`javascript:`, `vbscript:`, `file:`, and `data:` except for `image/png`, `image/gif`, `image/jpeg`, or `image/webp` mime types). Otherwise, raw HTML is replaced by a placeholder HTML comment, and unsafe links are replaced with empty strings. |\n| `extensions`* | `object` | Which extensions to enable |\n| *\\* more information in the Features and Extensions sections below* |\n\nlibcmark-gfm also exposes several Markdown extensions that you can enable by passing their name as keys to the `extensions` option (with a value of `true`). You can find a summary of all the extensions in the table below, as well as additional information in the *Extensions* section later in this document.\n\n| Name | Description |\n|---|---|\n| `\"table\"` | Renders tables |\n| `\"strikethrough\"` | Renders text as strikethrough when surrounded by `~tildes~` |\n| `\"tagfilter\"` | Escapes [certain dangerous HTML tags](https://github.github.com/gfm/#disallowed-raw-html-extension-), causing them to have no effect |\n| `\"autolink\"` | Automatically generates links from URLs |\n| `\"tasklist\"` | Renders [GitHub-style task lists](https://help.github.com/articles/about-task-lists/)\n\n## Features\n\n### `sourcepos`\n\nEnabling the `sourcepos` option adds a `data-sourcepos` attribute to block level elements which indicate the row and column positions from the original Markdown source that resulted in that HTML element. For example, given the markdown:\n\n````markdown\n# Hello!\n\nHi there. This is a Markdown file. You probably knew that already.\n\n```javascript\n// Here's a bit of JS code\n\nconsole.log('hello')\n```\n\nAnd a short list:\n\n* One\n* Two\n* Three\n````\n\nRendering with the `sourcepos` attribute would result in output similar to:\n\n```html\n\u003ch1 data-sourcepos=\"1:1-1:8\"\u003eHello!\u003c/h1\u003e\n\n\u003cp data-sourcepos=\"3:1-3:66\"\u003eHi there. This is a Markdown file. You probably knew that already.\u003c/p\u003e\n\n\u003cpre data-sourcepos=\"5:1-9:3\"\u003e\n\u003ccode class=\"language-javascript\"\u003e\n// Here's a bit of JS code\n\nconsole.log('hello')\n\u003c/code\u003e\n\u003c/pre\u003e\n\n\u003cp data-sourcepos=\"11:1-11:17\"\u003eAnd a short list:\u003c/p\u003e\n\n\u003cul data-sourcepos=\"13:1-15:7\"\u003e\n  \u003cli data-sourcepos=\"13:1-13:5\"\u003eOne\u003c/li\u003e\n  \u003cli data-sourcepos=\"14:1-14:5\"\u003eTwo\u003c/li\u003e\n  \u003cli data-sourcepos=\"15:1-15:7\"\u003eThree\u003c/li\u003e\n\u003c/ul\u003e\n```\n\nYou can see, for example, that the `\u003cpre\u003e` tag that represents the code block was generated from the Markdown text between row 5 column 1 and row 9 column 3 (inclusive and 1-indexed).\n\n### `hardbreaks`\n\nEnabling the `hardbreaks` option renders \"softbreak\" elements as hard line breaks.\n\n```markdown\nabc\ndef\n```\n\nwould normally result in\n\n```html\n\u003cp\u003eabc\\ndef\u003c/p\u003e\n```\n\nbut with `hardbreaks` enabled, it results in\n\n```html\n\u003cp\u003eabc\u003cbr\u003e\\ndef\u003c/p\u003e\n```\n\n### `nobreaks`\n\nEnabling the `nobreaks` option renders \"softbreak\" elements as spaces:\n\n```markdown\nabc\ndef\n```\n\nwould normally result in\n\n```html\n\u003cp\u003eabc\\ndef\u003c/p\u003e\n```\n\nbut with `nobreaks` enabled, it results in\n\n```html\n\u003cp\u003eabc def\u003c/p\u003e\n```\n\n### `githubPreLang`\n\nNormally, code blocks like the following:\n\n````markdown\n```javascript\nconsole.log('hello!')\n```\n````\n\nwould result in HTML like this:\n\n```html\n\u003cpre\u003e\n\u003ccode class=\"language-javascript\"\u003e\nconsole.log('hello!')\n\u003c/code\u003e\n\u003c/pre\u003e\n```\n\nWith `githubPreLang` enabled, it would instead result in the following HTML:\n\n```html\n\u003cpre lang=\"javascript\"\u003e\n\u003ccode\u003e\nconsole.log('hello!')\n\u003c/code\u003e\n\u003c/pre\u003e\n```\n\n### `footnotes`\n\nEnabling the `footnotes` option turns on the parsing and rendering of footnotes. Here's a simple example:\n\n````markdown\nHere is some text[^1]. Here's a little bit more[^more].\n\n[^1]: You can tell because of all the text\n[^more]: Just a little bit\n````\n\nAnd the resulting HTML:\n\n```html\n\u003cp\u003eHere is some text\u003csup class=\"footnote-ref\"\u003e\u003ca href=\"#fn1\" id=\"fnref1\"\u003e1\u003c/a\u003e\u003c/sup\u003e. Here's a little bit more\u003csup class=\"footnote-ref\"\u003e\u003ca href=\"#fn2\" id=\"fnref2\"\u003e2\u003c/a\u003e\u003c/sup\u003e.\u003c/p\u003e\n\n\u003csection class=\"footnotes\"\u003e\n  \u003col\u003e\n    \u003cli id=\"fn1\"\u003e\n      \u003cp\u003eYou can tell because of all the text \u003ca href=\"#fnref1\" class=\"footnote-backref\"\u003e↩\u003c/a\u003e\u003c/p\u003e\n    \u003c/li\u003e\n    \u003cli id=\"fn2\"\u003e\n      \u003cp\u003eJust a little bit \u003ca href=\"#fnref2\" class=\"footnote-backref\"\u003e↩\u003c/a\u003e\u003c/p\u003e\n    \u003c/li\u003e\n  \u003c/ol\u003e\n\u003c/section\u003e\n```\n\n### `fullInfoString`\n\nWhen the `fullInfoString` feature is enabled, extra text after the language tag for a code block (which is normally discarded) is included in a `data-meta` attribute on the resulting HTML element:\n\n````markdown\n```javascript here is some more text\nconsole.log('hi')\n```\n````\n\n```html\n\u003cpre\u003e\n\u003ccode class=\"language-javascript\" data-meta=\"here is some more text\"\u003e\nconsole.log('hi')\n\u003c/code\u003e\n\u003c/pre\u003e\n```\n\n### `unsafe`\n\nBy default, `libcmark-gfm` escapes raw HTML and unsafe links:\n\n\n````markdown\n![img](data:image/gif;base64,abccdefgh)\n\n\u003cdiv\u003ehello!\u003c/div\u003e\n\n[link](javascript:alert('omg'))\n````\n\nwould result in:\n\n```html\n\u003cp\u003e\u003cimg alt=\"img\" src=\"data:image/gif;base64,abccdefgh\"\u003e\u003c/p\u003e\n\u003c!-- raw HTML omitted --\u003e\n\u003cp\u003e\u003ca href=\"\"\u003elink\u003c/a\u003e\u003c/p\u003e\n```\n\nNotice that the `div` and the `javascript:alert` link have been sanitized. With the `unsafe` option enabled, the resulting HTML would be:\n\n```html\n\u003cp\u003e\u003cimg alt=\"img\" src=\"data:image/gif;base64,abccdefgh\"\u003e\u003c/p\u003e\n\u003cdiv\u003ehello!\u003c/div\u003e\n\u003cp\u003e\u003ca href=\"javascript:alert('omg')\"\u003elink\u003c/a\u003e\u003c/p\u003e\n```\n\nIf you use the `unsafe` option, you should be sure to do your own sanitization of the resulting HTML.\n\n## Extensions\n\n### `\"table\"`\n\nThe `table` extension allows the parsing and rendering of tables:\n\n```markdown\n|Header|\n|------|\n|Hello |\n```\n\n```html\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eHeader\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eHello\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n```\n\nSee [the table documentation in the GFM docs](https://github.github.com/gfm/#tables-extension-) for more information.\n\n### `\"strikethrough\"`\n\nThe `strikethrough` extension renders text surrounded by `~one~` or `~~two~~` tildes as strikethrough using the `\u003cdel\u003e` tag. If the `strikethroughDoubleTilde` option is enabled, text will only be rendered as strikethrough if it is surrounded by exactly `~~two~~` tildes.\n\n### `\"tagfilter\"`\n\nCertain HTML tags can be particularly troublesome as they change how HTML is interpreted in a way unique to them. The `tagfilter` extension escapes these tags by replacing the leading `\u003c` with `\u0026lt;`. The following markdown:\n\n```markdown\n\u003cdiv\u003eWhat a weird \u003cxmp\u003e tag\u003c/div\u003e\n```\n\nwould result in this HTML:\n\n```html\n\u003cdiv\u003eWhat a weird \u0026lt;xmp\u003e tag\u003c/div\u003e\n```\n\nSee [the Disallowed Raw HTML documentation in the GFM docs](https://github.github.com/gfm/#disallowed-raw-html-extension-) for more information and the list of filtered tags.\n\n### `\"autolink\"`\n\nThe `autolink` extension recognizes URLs in text and automatically turns them into links:\n\n```markdown\nVisit us at https://github.com!\n```\n\n```html\n\u003cp\u003eVisit us at \u003ca href=\"https://github.com\"\u003ehttps://github.com\u003c/a\u003e!\u003c/p\u003e\n```\n\nSee [the autolinks documentation in the GFM docs](https://github.github.com/gfm/#autolinks-extension-) for more information about how libcmark-gfm scans for links.\n\n### `\"tasklist\"`\n\nThe `tasklist` extension enables the rendering of [GitHub-style task lists](https://help.github.com/articles/about-task-lists/).\n\n```markdown\n- [ ] Task 1\n- [x] Task 2\n```\n\n```html\n\u003cul\u003e\n  \u003cli class=\"task-list-item\"\u003e\u003cinput type=\"checkbox\" disabled=\"\" /\u003e Task 1\u003c/li\u003e\n  \u003cli class=\"task-list-item\"\u003e\u003cinput type=\"checkbox\" checked=\"\" disabled=\"\" /\u003e Task 2\u003c/li\u003e\n\u003c/ul\u003e\n```\n\nSee [the task list documentation in the GFM docs](https://github.github.com/gfm/#task-list-items-extension-) for more information about how libcmark-gfm processes task lists.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbinarymuse%2Fnode-cmark-gfm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbinarymuse%2Fnode-cmark-gfm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbinarymuse%2Fnode-cmark-gfm/lists"}