micromark-extension-gfm-footnote
Advanced tools
Comparing version 1.0.2 to 1.0.3
@@ -28,2 +28,3 @@ /** | ||
import {ok as assert} from 'uvu/assert' | ||
import {normalizeIdentifier} from 'micromark-util-normalize-identifier' | ||
@@ -48,4 +49,4 @@ import {sanitizeUri} from 'micromark-util-sanitize-uri' | ||
gfmFootnoteDefinition() { | ||
// @ts-expect-error It’s defined. | ||
this.getData('tightStack').push(false) | ||
const stack = /** @type {Array<boolean>} */ (this.getData('tightStack')) | ||
stack.push(false) | ||
}, | ||
@@ -61,19 +62,23 @@ gfmFootnoteDefinitionLabelString() { | ||
gfmFootnoteDefinition() { | ||
/** @type {Record<string, string>} */ | ||
// @ts-expect-error It’s fine. | ||
let definitions = this.getData('gfmFootnoteDefinitions') | ||
/** @type {string[]} */ | ||
// @ts-expect-error: It’s fine | ||
const stack = this.getData('gfmFootnoteDefinitionStack') | ||
/** @type {string} */ | ||
// @ts-expect-error: It’s fine | ||
const current = stack.pop() | ||
let definitions = /** @type {Record<string, string>} */ ( | ||
this.getData('gfmFootnoteDefinitions') | ||
) | ||
const footnoteStack = /** @type {Array<string>} */ ( | ||
this.getData('gfmFootnoteDefinitionStack') | ||
) | ||
const tightStack = /** @type {Array<boolean>} */ ( | ||
this.getData('tightStack') | ||
) | ||
const current = footnoteStack.pop() | ||
const value = this.resume() | ||
if (!definitions) | ||
assert(current, 'expected to be in a footnote') | ||
if (!definitions) { | ||
this.setData('gfmFootnoteDefinitions', (definitions = {})) | ||
} | ||
if (!own.call(definitions, current)) definitions[current] = value | ||
// @ts-expect-error It’s defined. | ||
this.getData('tightStack').pop() | ||
tightStack.pop() | ||
this.setData('slurpOneLineEnding', true) | ||
@@ -85,9 +90,11 @@ // “Hack” to prevent a line ending from showing up if we’re in a definition in | ||
gfmFootnoteDefinitionLabelString(token) { | ||
/** @type {string[]} */ | ||
// @ts-expect-error: It’s fine | ||
let stack = this.getData('gfmFootnoteDefinitionStack') | ||
let footnoteStack = /** @type {Array<string>} */ ( | ||
this.getData('gfmFootnoteDefinitionStack') | ||
) | ||
if (!stack) this.setData('gfmFootnoteDefinitionStack', (stack = [])) | ||
if (!footnoteStack) { | ||
this.setData('gfmFootnoteDefinitionStack', (footnoteStack = [])) | ||
} | ||
stack.push(normalizeIdentifier(this.sliceSerialize(token))) | ||
footnoteStack.push(normalizeIdentifier(this.sliceSerialize(token))) | ||
this.resume() // Drop the label. | ||
@@ -97,8 +104,8 @@ this.buffer() // Get ready for a value. | ||
gfmFootnoteCallString(token) { | ||
/** @type {string[]|undefined} */ | ||
// @ts-expect-error It’s fine. | ||
let calls = this.getData('gfmFootnoteCallOrder') | ||
/** @type {Record.<string, number>|undefined} */ | ||
// @ts-expect-error It’s fine. | ||
let counts = this.getData('gfmFootnoteCallCounts') | ||
let calls = /** @type {Array<string>|undefined} */ ( | ||
this.getData('gfmFootnoteCallOrder') | ||
) | ||
let counts = /** @type {Record<string, number>|undefined} */ ( | ||
this.getData('gfmFootnoteCallCounts') | ||
) | ||
const id = normalizeIdentifier(this.sliceSerialize(token)) | ||
@@ -143,11 +150,11 @@ /** @type {number} */ | ||
null() { | ||
/** @type {string[]} */ | ||
// @ts-expect-error It’s fine. | ||
const calls = this.getData('gfmFootnoteCallOrder') || [] | ||
/** @type {Record.<string, number>} */ | ||
// @ts-expect-error It’s fine. | ||
const counts = this.getData('gfmFootnoteCallCounts') || {} | ||
/** @type {Record<string, string>} */ | ||
// @ts-expect-error It’s fine. | ||
const definitions = this.getData('gfmFootnoteDefinitions') || {} | ||
const calls = /** @type {Array<string>} */ ( | ||
this.getData('gfmFootnoteCallOrder') || [] | ||
) | ||
const counts = /** @type {Record<string, number>} */ ( | ||
this.getData('gfmFootnoteCallCounts') || {} | ||
) | ||
const definitions = /** @type {Record<string, string>} */ ( | ||
this.getData('gfmFootnoteDefinitions') || {} | ||
) | ||
let index = -1 | ||
@@ -171,3 +178,3 @@ | ||
let referenceIndex = 0 | ||
/** @type {string[]} */ | ||
/** @type {Array<string>} */ | ||
const references = [] | ||
@@ -174,0 +181,0 @@ |
@@ -53,3 +53,3 @@ /** | ||
let index = self.events.length | ||
/** @type {string[]} */ | ||
/** @type {Array<string>} */ | ||
// @ts-expect-error It’s fine! | ||
@@ -157,3 +157,3 @@ const defined = self.parser.gfmFootnotes || (self.parser.gfmFootnotes = []) | ||
/** @type {Event[]} */ | ||
/** @type {Array<Event>} */ | ||
const replacement = [ | ||
@@ -189,3 +189,3 @@ // Take the `labelImageMarker` (now `data`, the `!`) | ||
const self = this | ||
/** @type {string[]} */ | ||
/** @type {Array<string>} */ | ||
// @ts-expect-error It’s fine! | ||
@@ -284,3 +284,3 @@ const defined = self.parser.gfmFootnotes || (self.parser.gfmFootnotes = []) | ||
const self = this | ||
/** @type {string[]} */ | ||
/** @type {Array<string>} */ | ||
// @ts-expect-error It’s fine! | ||
@@ -287,0 +287,0 @@ const defined = self.parser.gfmFootnotes || (self.parser.gfmFootnotes = []) |
@@ -45,4 +45,6 @@ /** | ||
gfmFootnoteDefinition() { | ||
// @ts-expect-error It’s defined. | ||
this.getData('tightStack').push(false) | ||
const stack = | ||
/** @type {Array<boolean>} */ | ||
this.getData('tightStack') | ||
stack.push(false) | ||
}, | ||
@@ -60,19 +62,20 @@ | ||
gfmFootnoteDefinition() { | ||
/** @type {Record<string, string>} */ | ||
// @ts-expect-error It’s fine. | ||
let definitions = this.getData('gfmFootnoteDefinitions') | ||
/** @type {string[]} */ | ||
// @ts-expect-error: It’s fine | ||
let definitions = | ||
/** @type {Record<string, string>} */ | ||
this.getData('gfmFootnoteDefinitions') | ||
const footnoteStack = | ||
/** @type {Array<string>} */ | ||
this.getData('gfmFootnoteDefinitionStack') | ||
const tightStack = | ||
/** @type {Array<boolean>} */ | ||
this.getData('tightStack') | ||
const current = footnoteStack.pop() | ||
const value = this.resume() | ||
const stack = this.getData('gfmFootnoteDefinitionStack') | ||
/** @type {string} */ | ||
// @ts-expect-error: It’s fine | ||
const current = stack.pop() | ||
const value = this.resume() | ||
if (!definitions) | ||
if (!definitions) { | ||
this.setData('gfmFootnoteDefinitions', (definitions = {})) | ||
if (!own.call(definitions, current)) definitions[current] = value // @ts-expect-error It’s defined. | ||
} | ||
this.getData('tightStack').pop() | ||
if (!own.call(definitions, current)) definitions[current] = value | ||
tightStack.pop() | ||
this.setData('slurpOneLineEnding', true) // “Hack” to prevent a line ending from showing up if we’re in a definition in | ||
@@ -85,7 +88,11 @@ // an empty list item. | ||
gfmFootnoteDefinitionLabelString(token) { | ||
/** @type {string[]} */ | ||
// @ts-expect-error: It’s fine | ||
let stack = this.getData('gfmFootnoteDefinitionStack') | ||
if (!stack) this.setData('gfmFootnoteDefinitionStack', (stack = [])) | ||
stack.push(normalizeIdentifier(this.sliceSerialize(token))) | ||
let footnoteStack = | ||
/** @type {Array<string>} */ | ||
this.getData('gfmFootnoteDefinitionStack') | ||
if (!footnoteStack) { | ||
this.setData('gfmFootnoteDefinitionStack', (footnoteStack = [])) | ||
} | ||
footnoteStack.push(normalizeIdentifier(this.sliceSerialize(token))) | ||
this.resume() // Drop the label. | ||
@@ -97,9 +104,8 @@ | ||
gfmFootnoteCallString(token) { | ||
/** @type {string[]|undefined} */ | ||
// @ts-expect-error It’s fine. | ||
let calls = this.getData('gfmFootnoteCallOrder') | ||
/** @type {Record.<string, number>|undefined} */ | ||
// @ts-expect-error It’s fine. | ||
let counts = this.getData('gfmFootnoteCallCounts') | ||
let calls = | ||
/** @type {Array<string>|undefined} */ | ||
this.getData('gfmFootnoteCallOrder') | ||
let counts = | ||
/** @type {Record<string, number>|undefined} */ | ||
this.getData('gfmFootnoteCallCounts') | ||
const id = normalizeIdentifier(this.sliceSerialize(token)) | ||
@@ -142,13 +148,11 @@ /** @type {number} */ | ||
null() { | ||
/** @type {string[]} */ | ||
// @ts-expect-error It’s fine. | ||
const calls = this.getData('gfmFootnoteCallOrder') || [] | ||
/** @type {Record.<string, number>} */ | ||
// @ts-expect-error It’s fine. | ||
const counts = this.getData('gfmFootnoteCallCounts') || {} | ||
/** @type {Record<string, string>} */ | ||
// @ts-expect-error It’s fine. | ||
const definitions = this.getData('gfmFootnoteDefinitions') || {} | ||
const calls = | ||
/** @type {Array<string>} */ | ||
this.getData('gfmFootnoteCallOrder') || [] | ||
const counts = | ||
/** @type {Record<string, number>} */ | ||
this.getData('gfmFootnoteCallCounts') || {} | ||
const definitions = | ||
/** @type {Record<string, string>} */ | ||
this.getData('gfmFootnoteDefinitions') || {} | ||
let index = -1 | ||
@@ -172,3 +176,3 @@ | ||
let referenceIndex = 0 | ||
/** @type {string[]} */ | ||
/** @type {Array<string>} */ | ||
@@ -175,0 +179,0 @@ const references = [] |
@@ -54,3 +54,3 @@ /** | ||
let index = self.events.length | ||
/** @type {string[]} */ | ||
/** @type {Array<string>} */ | ||
// @ts-expect-error It’s fine! | ||
@@ -155,3 +155,3 @@ | ||
} | ||
/** @type {Event[]} */ | ||
/** @type {Array<Event>} */ | ||
@@ -182,3 +182,3 @@ const replacement = [ | ||
const self = this | ||
/** @type {string[]} */ | ||
/** @type {Array<string>} */ | ||
// @ts-expect-error It’s fine! | ||
@@ -267,3 +267,3 @@ | ||
const self = this | ||
/** @type {string[]} */ | ||
/** @type {Array<string>} */ | ||
// @ts-expect-error It’s fine! | ||
@@ -270,0 +270,0 @@ |
{ | ||
"name": "micromark-extension-gfm-footnote", | ||
"version": "1.0.2", | ||
"version": "1.0.3", | ||
"description": "micromark extension to support GFM footnotes", | ||
@@ -52,2 +52,3 @@ "license": "MIT", | ||
"c8": "^7.0.0", | ||
"create-gfm-fixtures": "^1.0.0", | ||
"micromark": "^3.0.0", | ||
@@ -62,3 +63,3 @@ "micromark-build": "^1.0.0", | ||
"typescript": "^4.0.0", | ||
"xo": "^0.45.0" | ||
"xo": "^0.47.0" | ||
}, | ||
@@ -83,2 +84,3 @@ "scripts": { | ||
"rules": { | ||
"unicorn/prefer-code-point": "off", | ||
"node/file-extension-in-import": "off", | ||
@@ -85,0 +87,0 @@ "unicorn/no-this-assignment": "off", |
123
readme.md
@@ -11,8 +11,30 @@ # micromark-extension-gfm-footnote | ||
**[micromark][]** extension to support GitHub Flavored Markdown (GFM) footnotes. | ||
GFM footnotes were [announced September 30, 2021][post] but are neither | ||
specified nor supported in all their products (e.g., Gists). | ||
**[micromark][]** extension to support GitHub flavored markdown (GFM) | ||
[footnotes][post]. | ||
## Contents | ||
* [What is this?](#what-is-this) | ||
* [When to use this](#when-to-use-this) | ||
* [Install](#install) | ||
* [Use](#use) | ||
* [API](#api) | ||
* [`gfmFootnote()`](#gfmfootnote) | ||
* [`gfmFootnoteHtml(htmlOptions)`](#gfmfootnotehtmlhtmloptions) | ||
* [Recommended CSS](#recommended-css) | ||
* [Types](#types) | ||
* [Compatibility](#compatibility) | ||
* [Security](#security) | ||
* [Related](#related) | ||
* [Contribute](#contribute) | ||
* [License](#license) | ||
## What is this? | ||
This package is a micromark extension to add support for GFM footnotes. | ||
GFM footnotes were [announced September 30, 2021][post] but are not yet | ||
specified. | ||
Their implementation on github.com is currently quite buggy. | ||
The bugs have been reported on | ||
[`cmark-gfm`](https://github.com/github/cmark-gfm). | ||
[`cmark-gfm`][cmark-gfm]. | ||
This micromark extension matches github.com except for its bugs. | ||
@@ -22,13 +44,19 @@ | ||
You should probably use [`micromark-extension-gfm`][micromark-extension-gfm] | ||
instead, which combines this package with other GFM features. | ||
Alternatively, if you don’t want all of GFM, use this package. | ||
In many cases, when working with micromark, you’d want to use | ||
[`micromark-extension-gfm`][micromark-extension-gfm] instead, which combines | ||
this package with other GFM features. | ||
When working with syntax trees, you’d want to combine this package with | ||
[`mdast-util-gfm-footnote`][mdast-util-gfm-footnote] (or | ||
[`mdast-util-gfm`][mdast-util-gfm] when using `micromark-extension-gfm`). | ||
These tools are all rather low-level. | ||
In most cases, you’d instead want to use [`remark-gfm`][remark-gfm] with | ||
[remark][]. | ||
## Install | ||
This package is [ESM only](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c): | ||
Node 12+ is needed to use it and it must be `import`ed instead of `require`d. | ||
This package is [ESM only][esm]. | ||
In Node.js (version 12.20+, 14.14+, or 16.0+), install with [npm][]: | ||
[npm][]: | ||
```sh | ||
@@ -38,5 +66,19 @@ npm install micromark-extension-gfm-footnote | ||
In Deno with [Skypack][]: | ||
```js | ||
import {gfmFootnote, gfmFootnoteHtml} from 'https://cdn.skypack.dev/micromark-extension-gfm-footnote@1?dts' | ||
``` | ||
In browsers with [Skypack][]: | ||
```html | ||
<script type="module"> | ||
import {gfmFootnote, gfmFootnoteHtml} from 'https://cdn.skypack.dev/micromark-extension-gfm-footnote@1?min' | ||
</script> | ||
``` | ||
## Use | ||
Say we have the following file, `example.md`: | ||
Say we have the following file `example.md`: | ||
@@ -61,3 +103,3 @@ ````markdown | ||
And our module, `example.js`, looks as follows: | ||
And our module `example.js` looks as follows: | ||
@@ -77,3 +119,3 @@ ```js | ||
Now, running `node example` yields: | ||
Now running `node example.js` yields: | ||
@@ -107,3 +149,3 @@ ```html | ||
The export map supports the endorsed | ||
[`development` condition](https://nodejs.org/api/packages.html#packages\_resolving\_user\_conditions). | ||
[`development` condition](https://nodejs.org/api/packages.html#packages_resolving_user_conditions). | ||
Run `node --conditions development module.js` to get instrumented dev code. | ||
@@ -114,7 +156,9 @@ Without this condition, production code is loaded. | ||
A function that can be called to get an extension for micromark to parse | ||
GFM footnotes (can be passed in `extensions`). | ||
### `gfmFootnoteHtml(htmlOptions)` | ||
A function that can be called to get an extension for micromark to parse | ||
GFM footnotes (can be passed in `extensions`) and a function that can be called | ||
to get an extension to compile them to HTML (can be passed in `htmlExtensions`). | ||
A function that can be called to get an extension to compile them to HTML (can | ||
be passed in `htmlExtensions`). | ||
@@ -184,16 +228,25 @@ ###### `htmlOptions.clobberPrefix` | ||
## Types | ||
This package is fully typed with [TypeScript][]. | ||
It exports additional `HtmlOptions` type that models its respective interface. | ||
## Compatibility | ||
This package is at least compatible with all maintained versions of Node.js. | ||
As of now, that is Node.js 12.20+, 14.14+, and 16.0+. | ||
It also works in Deno and modern browsers. | ||
## Security | ||
This package is safe. | ||
## Related | ||
* [`remarkjs/remark`][remark] | ||
— markdown processor powered by plugins | ||
* [`syntax-tree/mdast-util-gfm-footnote`][mdast-util-gfm-footnote] | ||
— support GFM footnotes in mdast | ||
* [`syntax-tree/mdast-util-gfm`][mdast-util-gfm] | ||
— support GFM in mdast | ||
* [`remarkjs/remark-gfm`][remark-gfm] | ||
— remark plugin using this to support all of GFM | ||
* [`micromark/micromark`][micromark] | ||
— the smallest commonmark-compliant markdown parser that exists | ||
* [`syntax-tree/mdast-util-gfm-footnote`][mdast-util-gfm-footnote] | ||
— mdast utility to support GFM footnotes | ||
* [`syntax-tree/mdast-util-from-markdown`][from-markdown] | ||
— mdast parser using `micromark` to create mdast from markdown | ||
* [`syntax-tree/mdast-util-to-markdown`][to-markdown] | ||
— mdast serializer to create markdown from mdast | ||
— support GFM in remark | ||
@@ -244,2 +297,4 @@ ## Contribute | ||
[skypack]: https://www.skypack.dev | ||
[license]: license | ||
@@ -255,7 +310,7 @@ | ||
[micromark]: https://github.com/micromark/micromark | ||
[esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c | ||
[from-markdown]: https://github.com/syntax-tree/mdast-util-from-markdown | ||
[typescript]: https://www.typescriptlang.org | ||
[to-markdown]: https://github.com/syntax-tree/mdast-util-to-markdown | ||
[micromark]: https://github.com/micromark/micromark | ||
@@ -268,4 +323,8 @@ [remark]: https://github.com/remarkjs/remark | ||
[mdast-util-gfm]: https://github.com/syntax-tree/mdast-util-gfm | ||
[remark-gfm]: https://github.com/remarkjs/remark-gfm | ||
[post]: https://github.blog/changelog/2021-09-30-footnotes-now-supported-in-markdown-fields/ | ||
[cmark-gfm]: https://github.com/github/cmark-gfm |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
53440
1264
320
13