Socket
Socket
Sign inDemoInstall

micromark-extension-gfm-footnote

Package Overview
Dependencies
Maintainers
0
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

micromark-extension-gfm-footnote - npm Package Compare versions

Comparing version 2.0.0 to 2.1.0

164

dev/index.d.ts

@@ -0,10 +1,151 @@

export {gfmFootnoteHtml, defaultBackLabel} from './lib/html.js'
export {gfmFootnote} from './lib/syntax.js'
export {
gfmFootnoteHtml,
defaultBackLabel,
type BackLabelTemplate,
type Options as HtmlOptions
} from './lib/html.js'
/**
* Generate a back label dynamically.
*
* For the following markdown:
*
* ```markdown
* Alpha[^micromark], bravo[^micromark], and charlie[^remark].
*
* [^remark]: things about remark
* [^micromark]: things about micromark
* ```
*
* This function will be called with:
*
* * `0` and `0` for the backreference from `things about micromark` to
* `alpha`, as it is the first used definition, and the first call to it
* * `0` and `1` for the backreference from `things about micromark` to
* `bravo`, as it is the first used definition, and the second call to it
* * `1` and `0` for the backreference from `things about remark` to
* `charlie`, as it is the second used definition
*
* @param referenceIndex
* Index of the definition in the order that they are first referenced,
* 0-indexed.
* @param rereferenceIndex
* Index of calls to the same definition, 0-indexed.
* @returns
* Back label to use when linking back from definitions to their reference.
*/
export type BackLabelTemplate = (
referenceIndex: number,
rereferenceIndex: number
) => string
/**
* Configuration.
*/
export interface HtmlOptions {
/**
* Prefix to use before the `id` attribute on footnotes to prevent them from
* *clobbering* (default: `'user-content-'`).
*
* Pass `''` for trusted markdown and when you are careful with
* polyfilling.
* You could pass a different prefix.
*
* DOM clobbering is this:
*
* ```html
* <p id="x"></p>
* <script>alert(x) // `x` now refers to the `p#x` DOM element</script>
* ```
*
* The above example shows that elements are made available by browsers, by
* their ID, on the `window` object.
* This is a security risk because you might be expecting some other variable
* at that place.
* It can also break polyfills.
* Using a prefix solves these problems.
*/
clobberPrefix?: string | null | undefined
/**
* Textual label to use for the footnotes section (default: `'Footnotes'`).
*
* Change it when the markdown is not in English.
*
* This label is typically hidden visually (assuming a `sr-only` CSS class
* is defined that does that) and so affects screen readers only.
* If you do have such a class, but want to show this section to everyone,
* pass different attributes with the `labelAttributes` option.
*/
label?: string | null | undefined
/**
* Attributes to use on the footnote label (default: `'class="sr-only"'`).
*
* Change it to show the label and add other attributes.
*
* This label is typically hidden visually (assuming an `sr-only` CSS class
* is defined that does that) and so affects screen readers only.
* If you do have such a class, but want to show this section to everyone,
* pass an empty string.
* You can also add different attributes.
*
* > 👉 **Note**: `id="footnote-label"` is always added, because footnote
* > calls use it with `aria-describedby` to provide an accessible label.
*/
labelAttributes?: string | null | undefined
/**
* HTML tag name to use for the footnote label element (default: `'h2'`).
*
* Change it to match your document structure.
*
* This label is typically hidden visually (assuming a `sr-only` CSS class
* is defined that does that) and so affects screen readers only.
* If you do have such a class, but want to show this section to everyone,
* pass different attributes with the `labelAttributes` option.
*/
labelTagName?: string | null | undefined
/**
* Textual label to describe the backreference back to references (default:
* `defaultBackLabel`).
*
* The default value is:
*
* ```js
* function defaultBackLabel(referenceIndex, rereferenceIndex) {
* return (
* 'Back to reference ' +
* (referenceIndex + 1) +
* (rereferenceIndex > 1 ? '-' + rereferenceIndex : '')
* )
* }
* ```
*
* Change it when the markdown is not in English.
*
* This label is used in the `aria-label` attribute on each backreference
* (the `↩` links).
* It affects users of assistive technology.
*/
backLabel?: BackLabelTemplate | string | null | undefined
}
/**
* Augment types.
*/
declare module 'micromark-util-types' {
/**
* Compile data.
*/
interface CompileData {
gfmFootnoteDefinitions?: Record<string, string>
gfmFootnoteDefinitionStack?: Array<string>
gfmFootnoteCallCounts?: Record<string, number>
gfmFootnoteCallOrder?: Array<string>
}
/**
* Parse context.
*/
interface ParseContext {
gfmFootnotes?: Array<string>
}
/**
* Token types.
*/
interface TokenTypeMap {

@@ -23,13 +164,2 @@ gfmFootnoteCall: 'gfmFootnoteCall'

}
interface ParseContext {
gfmFootnotes?: string[]
}
interface CompileData {
gfmFootnoteDefinitions?: Record<string, string>
gfmFootnoteDefinitionStack?: string[]
gfmFootnoteCallCounts?: Record<string, number>
gfmFootnoteCallOrder?: string[]
}
}

125

dev/lib/html.d.ts

@@ -12,6 +12,3 @@ /**

*/
export function defaultBackLabel(
referenceIndex: number,
rereferenceIndex: number
): string
export function defaultBackLabel(referenceIndex: number, rereferenceIndex: number): string;
/**

@@ -27,118 +24,4 @@ * Create an extension for `micromark` to support GFM footnotes when

*/
export function gfmFootnoteHtml(
options?: Options | null | undefined
): HtmlExtension
export type HtmlExtension = import('micromark-util-types').HtmlExtension
/**
* Generate a back label dynamically.
*
* For the following markdown:
*
* ```markdown
* Alpha[^micromark], bravo[^micromark], and charlie[^remark].
*
* [^remark]: things about remark
* [^micromark]: things about micromark
* ```
*
* This function will be called with:
*
* * `0` and `0` for the backreference from `things about micromark` to
* `alpha`, as it is the first used definition, and the first call to it
* * `0` and `1` for the backreference from `things about micromark` to
* `bravo`, as it is the first used definition, and the second call to it
* * `1` and `0` for the backreference from `things about remark` to
* `charlie`, as it is the second used definition
*/
export type BackLabelTemplate = (
referenceIndex: number,
rereferenceIndex: number
) => string
/**
* Configuration.
*/
export type Options = {
/**
* Prefix to use before the `id` attribute on footnotes to prevent them from
* *clobbering* (default: `'user-content-'`).
*
* Pass `''` for trusted markdown and when you are careful with
* polyfilling.
* You could pass a different prefix.
*
* DOM clobbering is this:
*
* ```html
* <p id="x"></p>
* <script>alert(x) // `x` now refers to the `p#x` DOM element</script>
* ```
*
* The above example shows that elements are made available by browsers, by
* their ID, on the `window` object.
* This is a security risk because you might be expecting some other variable
* at that place.
* It can also break polyfills.
* Using a prefix solves these problems.
*/
clobberPrefix?: string | null | undefined
/**
* Textual label to use for the footnotes section (default: `'Footnotes'`).
*
* Change it when the markdown is not in English.
*
* This label is typically hidden visually (assuming a `sr-only` CSS class
* is defined that does that) and so affects screen readers only.
* If you do have such a class, but want to show this section to everyone,
* pass different attributes with the `labelAttributes` option.
*/
label?: string | null | undefined
/**
* Attributes to use on the footnote label (default: `'class="sr-only"'`).
*
* Change it to show the label and add other attributes.
*
* This label is typically hidden visually (assuming an `sr-only` CSS class
* is defined that does that) and so affects screen readers only.
* If you do have such a class, but want to show this section to everyone,
* pass an empty string.
* You can also add different attributes.
*
* > 👉 **Note**: `id="footnote-label"` is always added, because footnote
* > calls use it with `aria-describedby` to provide an accessible label.
*/
labelAttributes?: string | null | undefined
/**
* HTML tag name to use for the footnote label element (default: `'h2'`).
*
* Change it to match your document structure.
*
* This label is typically hidden visually (assuming a `sr-only` CSS class
* is defined that does that) and so affects screen readers only.
* If you do have such a class, but want to show this section to everyone,
* pass different attributes with the `labelAttributes` option.
*/
labelTagName?: string | null | undefined
/**
* Textual label to describe the backreference back to references (default:
* `defaultBackLabel`).
*
* The default value is:
*
* ```js
* function defaultBackLabel(referenceIndex, rereferenceIndex) {
* return (
* 'Back to reference ' +
* (referenceIndex + 1) +
* (rereferenceIndex > 1 ? '-' + rereferenceIndex : '')
* )
* }
* ```
*
* Change it when the markdown is not in English.
*
* This label is used in the `aria-label` attribute on each backreference
* (the `↩` links).
* It affects users of assistive technology.
*/
backLabel?: BackLabelTemplate | string | null | undefined
}
export function gfmFootnoteHtml(options?: Options | null | undefined): HtmlExtension;
import type { HtmlOptions as Options } from 'micromark-extension-gfm-footnote';
import type { HtmlExtension } from 'micromark-util-types';
/**
* @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension
* @import {HtmlOptions as Options} from 'micromark-extension-gfm-footnote'
* @import {HtmlExtension} from 'micromark-util-types'
*/
/**
* @callback BackLabelTemplate
* Generate a back label dynamically.
*
* For the following markdown:
*
* ```markdown
* Alpha[^micromark], bravo[^micromark], and charlie[^remark].
*
* [^remark]: things about remark
* [^micromark]: things about micromark
* ```
*
* This function will be called with:
*
* * `0` and `0` for the backreference from `things about micromark` to
* `alpha`, as it is the first used definition, and the first call to it
* * `0` and `1` for the backreference from `things about micromark` to
* `bravo`, as it is the first used definition, and the second call to it
* * `1` and `0` for the backreference from `things about remark` to
* `charlie`, as it is the second used definition
* @param {number} referenceIndex
* Index of the definition in the order that they are first referenced,
* 0-indexed.
* @param {number} rereferenceIndex
* Index of calls to the same definition, 0-indexed.
* @returns {string}
* Back label to use when linking back from definitions to their reference.
*/
/**
* @typedef Options
* Configuration.
* @property {string | null | undefined} [clobberPrefix='user-content-']
* Prefix to use before the `id` attribute on footnotes to prevent them from
* *clobbering* (default: `'user-content-'`).
*
* Pass `''` for trusted markdown and when you are careful with
* polyfilling.
* You could pass a different prefix.
*
* DOM clobbering is this:
*
* ```html
* <p id="x"></p>
* <script>alert(x) // `x` now refers to the `p#x` DOM element</script>
* ```
*
* The above example shows that elements are made available by browsers, by
* their ID, on the `window` object.
* This is a security risk because you might be expecting some other variable
* at that place.
* It can also break polyfills.
* Using a prefix solves these problems.
* @property {string | null | undefined} [label='Footnotes']
* Textual label to use for the footnotes section (default: `'Footnotes'`).
*
* Change it when the markdown is not in English.
*
* This label is typically hidden visually (assuming a `sr-only` CSS class
* is defined that does that) and so affects screen readers only.
* If you do have such a class, but want to show this section to everyone,
* pass different attributes with the `labelAttributes` option.
* @property {string | null | undefined} [labelAttributes='class="sr-only"']
* Attributes to use on the footnote label (default: `'class="sr-only"'`).
*
* Change it to show the label and add other attributes.
*
* This label is typically hidden visually (assuming an `sr-only` CSS class
* is defined that does that) and so affects screen readers only.
* If you do have such a class, but want to show this section to everyone,
* pass an empty string.
* You can also add different attributes.
*
* > 👉 **Note**: `id="footnote-label"` is always added, because footnote
* > calls use it with `aria-describedby` to provide an accessible label.
* @property {string | null | undefined} [labelTagName='h2']
* HTML tag name to use for the footnote label element (default: `'h2'`).
*
* Change it to match your document structure.
*
* This label is typically hidden visually (assuming a `sr-only` CSS class
* is defined that does that) and so affects screen readers only.
* If you do have such a class, but want to show this section to everyone,
* pass different attributes with the `labelAttributes` option.
* @property {BackLabelTemplate | string | null | undefined} [backLabel]
* Textual label to describe the backreference back to references (default:
* `defaultBackLabel`).
*
* The default value is:
*
* ```js
* function defaultBackLabel(referenceIndex, rereferenceIndex) {
* return (
* 'Back to reference ' +
* (referenceIndex + 1) +
* (rereferenceIndex > 1 ? '-' + rereferenceIndex : '')
* )
* }
* ```
*
* Change it when the markdown is not in English.
*
* This label is used in the `aria-label` attribute on each backreference
* (the `↩` links).
* It affects users of assistive technology.
*/
import {ok as assert} from 'devlop'

@@ -114,0 +7,0 @@ import {normalizeIdentifier} from 'micromark-util-normalize-identifier'

@@ -8,10 +8,3 @@ /**

*/
export function gfmFootnote(): Extension
export type Event = import('micromark-util-types').Event
export type Exiter = import('micromark-util-types').Exiter
export type Extension = import('micromark-util-types').Extension
export type Resolver = import('micromark-util-types').Resolver
export type State = import('micromark-util-types').State
export type Token = import('micromark-util-types').Token
export type TokenizeContext = import('micromark-util-types').TokenizeContext
export type Tokenizer = import('micromark-util-types').Tokenizer
export function gfmFootnote(): Extension;
import type { Extension } from 'micromark-util-types';
/**
* @typedef {import('micromark-util-types').Event} Event
* @typedef {import('micromark-util-types').Exiter} Exiter
* @typedef {import('micromark-util-types').Extension} Extension
* @typedef {import('micromark-util-types').Resolver} Resolver
* @typedef {import('micromark-util-types').State} State
* @typedef {import('micromark-util-types').Token} Token
* @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext
* @typedef {import('micromark-util-types').Tokenizer} Tokenizer
* @import {Event, Exiter, Extension, Resolver, State, Token, TokenizeContext, Tokenizer} from 'micromark-util-types'
*/

@@ -39,2 +32,3 @@

[codes.leftSquareBracket]: {
name: 'gfmFootnoteDefinition',
tokenize: tokenizeDefinitionStart,

@@ -46,4 +40,8 @@ continuation: {tokenize: tokenizeDefinitionContinuation},

text: {
[codes.leftSquareBracket]: {tokenize: tokenizeGfmFootnoteCall},
[codes.leftSquareBracket]: {
name: 'gfmFootnoteCall',
tokenize: tokenizeGfmFootnoteCall
},
[codes.rightSquareBracket]: {
name: 'gfmPotentialFootnoteCall',
add: 'after',

@@ -50,0 +48,0 @@ tokenize: tokenizePotentialGfmFootnoteCall,

@@ -0,10 +1,151 @@

export {gfmFootnoteHtml, defaultBackLabel} from './lib/html.js'
export {gfmFootnote} from './lib/syntax.js'
export {
gfmFootnoteHtml,
defaultBackLabel,
type BackLabelTemplate,
type Options as HtmlOptions
} from './lib/html.js'
/**
* Generate a back label dynamically.
*
* For the following markdown:
*
* ```markdown
* Alpha[^micromark], bravo[^micromark], and charlie[^remark].
*
* [^remark]: things about remark
* [^micromark]: things about micromark
* ```
*
* This function will be called with:
*
* * `0` and `0` for the backreference from `things about micromark` to
* `alpha`, as it is the first used definition, and the first call to it
* * `0` and `1` for the backreference from `things about micromark` to
* `bravo`, as it is the first used definition, and the second call to it
* * `1` and `0` for the backreference from `things about remark` to
* `charlie`, as it is the second used definition
*
* @param referenceIndex
* Index of the definition in the order that they are first referenced,
* 0-indexed.
* @param rereferenceIndex
* Index of calls to the same definition, 0-indexed.
* @returns
* Back label to use when linking back from definitions to their reference.
*/
export type BackLabelTemplate = (
referenceIndex: number,
rereferenceIndex: number
) => string
/**
* Configuration.
*/
export interface HtmlOptions {
/**
* Prefix to use before the `id` attribute on footnotes to prevent them from
* *clobbering* (default: `'user-content-'`).
*
* Pass `''` for trusted markdown and when you are careful with
* polyfilling.
* You could pass a different prefix.
*
* DOM clobbering is this:
*
* ```html
* <p id="x"></p>
* <script>alert(x) // `x` now refers to the `p#x` DOM element</script>
* ```
*
* The above example shows that elements are made available by browsers, by
* their ID, on the `window` object.
* This is a security risk because you might be expecting some other variable
* at that place.
* It can also break polyfills.
* Using a prefix solves these problems.
*/
clobberPrefix?: string | null | undefined
/**
* Textual label to use for the footnotes section (default: `'Footnotes'`).
*
* Change it when the markdown is not in English.
*
* This label is typically hidden visually (assuming a `sr-only` CSS class
* is defined that does that) and so affects screen readers only.
* If you do have such a class, but want to show this section to everyone,
* pass different attributes with the `labelAttributes` option.
*/
label?: string | null | undefined
/**
* Attributes to use on the footnote label (default: `'class="sr-only"'`).
*
* Change it to show the label and add other attributes.
*
* This label is typically hidden visually (assuming an `sr-only` CSS class
* is defined that does that) and so affects screen readers only.
* If you do have such a class, but want to show this section to everyone,
* pass an empty string.
* You can also add different attributes.
*
* > 👉 **Note**: `id="footnote-label"` is always added, because footnote
* > calls use it with `aria-describedby` to provide an accessible label.
*/
labelAttributes?: string | null | undefined
/**
* HTML tag name to use for the footnote label element (default: `'h2'`).
*
* Change it to match your document structure.
*
* This label is typically hidden visually (assuming a `sr-only` CSS class
* is defined that does that) and so affects screen readers only.
* If you do have such a class, but want to show this section to everyone,
* pass different attributes with the `labelAttributes` option.
*/
labelTagName?: string | null | undefined
/**
* Textual label to describe the backreference back to references (default:
* `defaultBackLabel`).
*
* The default value is:
*
* ```js
* function defaultBackLabel(referenceIndex, rereferenceIndex) {
* return (
* 'Back to reference ' +
* (referenceIndex + 1) +
* (rereferenceIndex > 1 ? '-' + rereferenceIndex : '')
* )
* }
* ```
*
* Change it when the markdown is not in English.
*
* This label is used in the `aria-label` attribute on each backreference
* (the `↩` links).
* It affects users of assistive technology.
*/
backLabel?: BackLabelTemplate | string | null | undefined
}
/**
* Augment types.
*/
declare module 'micromark-util-types' {
/**
* Compile data.
*/
interface CompileData {
gfmFootnoteDefinitions?: Record<string, string>
gfmFootnoteDefinitionStack?: Array<string>
gfmFootnoteCallCounts?: Record<string, number>
gfmFootnoteCallOrder?: Array<string>
}
/**
* Parse context.
*/
interface ParseContext {
gfmFootnotes?: Array<string>
}
/**
* Token types.
*/
interface TokenTypeMap {

@@ -23,13 +164,2 @@ gfmFootnoteCall: 'gfmFootnoteCall'

}
interface ParseContext {
gfmFootnotes?: string[]
}
interface CompileData {
gfmFootnoteDefinitions?: Record<string, string>
gfmFootnoteDefinitionStack?: string[]
gfmFootnoteCallCounts?: Record<string, number>
gfmFootnoteCallOrder?: string[]
}
}
// Note: types are exported from `dev/index.d.ts`.
export {gfmFootnote} from './lib/syntax.js'
export {gfmFootnoteHtml, defaultBackLabel} from './lib/html.js'
export { gfmFootnote } from './lib/syntax.js';
export { gfmFootnoteHtml, defaultBackLabel } from './lib/html.js';

@@ -12,6 +12,3 @@ /**

*/
export function defaultBackLabel(
referenceIndex: number,
rereferenceIndex: number
): string
export function defaultBackLabel(referenceIndex: number, rereferenceIndex: number): string;
/**

@@ -27,118 +24,4 @@ * Create an extension for `micromark` to support GFM footnotes when

*/
export function gfmFootnoteHtml(
options?: Options | null | undefined
): HtmlExtension
export type HtmlExtension = import('micromark-util-types').HtmlExtension
/**
* Generate a back label dynamically.
*
* For the following markdown:
*
* ```markdown
* Alpha[^micromark], bravo[^micromark], and charlie[^remark].
*
* [^remark]: things about remark
* [^micromark]: things about micromark
* ```
*
* This function will be called with:
*
* * `0` and `0` for the backreference from `things about micromark` to
* `alpha`, as it is the first used definition, and the first call to it
* * `0` and `1` for the backreference from `things about micromark` to
* `bravo`, as it is the first used definition, and the second call to it
* * `1` and `0` for the backreference from `things about remark` to
* `charlie`, as it is the second used definition
*/
export type BackLabelTemplate = (
referenceIndex: number,
rereferenceIndex: number
) => string
/**
* Configuration.
*/
export type Options = {
/**
* Prefix to use before the `id` attribute on footnotes to prevent them from
* *clobbering* (default: `'user-content-'`).
*
* Pass `''` for trusted markdown and when you are careful with
* polyfilling.
* You could pass a different prefix.
*
* DOM clobbering is this:
*
* ```html
* <p id="x"></p>
* <script>alert(x) // `x` now refers to the `p#x` DOM element</script>
* ```
*
* The above example shows that elements are made available by browsers, by
* their ID, on the `window` object.
* This is a security risk because you might be expecting some other variable
* at that place.
* It can also break polyfills.
* Using a prefix solves these problems.
*/
clobberPrefix?: string | null | undefined
/**
* Textual label to use for the footnotes section (default: `'Footnotes'`).
*
* Change it when the markdown is not in English.
*
* This label is typically hidden visually (assuming a `sr-only` CSS class
* is defined that does that) and so affects screen readers only.
* If you do have such a class, but want to show this section to everyone,
* pass different attributes with the `labelAttributes` option.
*/
label?: string | null | undefined
/**
* Attributes to use on the footnote label (default: `'class="sr-only"'`).
*
* Change it to show the label and add other attributes.
*
* This label is typically hidden visually (assuming an `sr-only` CSS class
* is defined that does that) and so affects screen readers only.
* If you do have such a class, but want to show this section to everyone,
* pass an empty string.
* You can also add different attributes.
*
* > 👉 **Note**: `id="footnote-label"` is always added, because footnote
* > calls use it with `aria-describedby` to provide an accessible label.
*/
labelAttributes?: string | null | undefined
/**
* HTML tag name to use for the footnote label element (default: `'h2'`).
*
* Change it to match your document structure.
*
* This label is typically hidden visually (assuming a `sr-only` CSS class
* is defined that does that) and so affects screen readers only.
* If you do have such a class, but want to show this section to everyone,
* pass different attributes with the `labelAttributes` option.
*/
labelTagName?: string | null | undefined
/**
* Textual label to describe the backreference back to references (default:
* `defaultBackLabel`).
*
* The default value is:
*
* ```js
* function defaultBackLabel(referenceIndex, rereferenceIndex) {
* return (
* 'Back to reference ' +
* (referenceIndex + 1) +
* (rereferenceIndex > 1 ? '-' + rereferenceIndex : '')
* )
* }
* ```
*
* Change it when the markdown is not in English.
*
* This label is used in the `aria-label` attribute on each backreference
* (the `↩` links).
* It affects users of assistive technology.
*/
backLabel?: BackLabelTemplate | string | null | undefined
}
export function gfmFootnoteHtml(options?: Options | null | undefined): HtmlExtension;
import type { HtmlOptions as Options } from 'micromark-extension-gfm-footnote';
import type { HtmlExtension } from 'micromark-util-types';
/**
* @typedef {import('micromark-util-types').HtmlExtension} HtmlExtension
* @import {HtmlOptions as Options} from 'micromark-extension-gfm-footnote'
* @import {HtmlExtension} from 'micromark-util-types'
*/
/**
* @callback BackLabelTemplate
* Generate a back label dynamically.
*
* For the following markdown:
*
* ```markdown
* Alpha[^micromark], bravo[^micromark], and charlie[^remark].
*
* [^remark]: things about remark
* [^micromark]: things about micromark
* ```
*
* This function will be called with:
*
* * `0` and `0` for the backreference from `things about micromark` to
* `alpha`, as it is the first used definition, and the first call to it
* * `0` and `1` for the backreference from `things about micromark` to
* `bravo`, as it is the first used definition, and the second call to it
* * `1` and `0` for the backreference from `things about remark` to
* `charlie`, as it is the second used definition
* @param {number} referenceIndex
* Index of the definition in the order that they are first referenced,
* 0-indexed.
* @param {number} rereferenceIndex
* Index of calls to the same definition, 0-indexed.
* @returns {string}
* Back label to use when linking back from definitions to their reference.
*/
import { normalizeIdentifier } from 'micromark-util-normalize-identifier';
import { sanitizeUri } from 'micromark-util-sanitize-uri';
const own = {}.hasOwnProperty;
/**
* @typedef Options
* Configuration.
* @property {string | null | undefined} [clobberPrefix='user-content-']
* Prefix to use before the `id` attribute on footnotes to prevent them from
* *clobbering* (default: `'user-content-'`).
*
* Pass `''` for trusted markdown and when you are careful with
* polyfilling.
* You could pass a different prefix.
*
* DOM clobbering is this:
*
* ```html
* <p id="x"></p>
* <script>alert(x) // `x` now refers to the `p#x` DOM element</script>
* ```
*
* The above example shows that elements are made available by browsers, by
* their ID, on the `window` object.
* This is a security risk because you might be expecting some other variable
* at that place.
* It can also break polyfills.
* Using a prefix solves these problems.
* @property {string | null | undefined} [label='Footnotes']
* Textual label to use for the footnotes section (default: `'Footnotes'`).
*
* Change it when the markdown is not in English.
*
* This label is typically hidden visually (assuming a `sr-only` CSS class
* is defined that does that) and so affects screen readers only.
* If you do have such a class, but want to show this section to everyone,
* pass different attributes with the `labelAttributes` option.
* @property {string | null | undefined} [labelAttributes='class="sr-only"']
* Attributes to use on the footnote label (default: `'class="sr-only"'`).
*
* Change it to show the label and add other attributes.
*
* This label is typically hidden visually (assuming an `sr-only` CSS class
* is defined that does that) and so affects screen readers only.
* If you do have such a class, but want to show this section to everyone,
* pass an empty string.
* You can also add different attributes.
*
* > 👉 **Note**: `id="footnote-label"` is always added, because footnote
* > calls use it with `aria-describedby` to provide an accessible label.
* @property {string | null | undefined} [labelTagName='h2']
* HTML tag name to use for the footnote label element (default: `'h2'`).
*
* Change it to match your document structure.
*
* This label is typically hidden visually (assuming a `sr-only` CSS class
* is defined that does that) and so affects screen readers only.
* If you do have such a class, but want to show this section to everyone,
* pass different attributes with the `labelAttributes` option.
* @property {BackLabelTemplate | string | null | undefined} [backLabel]
* Textual label to describe the backreference back to references (default:
* `defaultBackLabel`).
*
* The default value is:
*
* ```js
* function defaultBackLabel(referenceIndex, rereferenceIndex) {
* return (
* 'Back to reference ' +
* (referenceIndex + 1) +
* (rereferenceIndex > 1 ? '-' + rereferenceIndex : '')
* )
* }
* ```
*
* Change it when the markdown is not in English.
*
* This label is used in the `aria-label` attribute on each backreference
* (the `↩` links).
* It affects users of assistive technology.
*/
import {normalizeIdentifier} from 'micromark-util-normalize-identifier'
import {sanitizeUri} from 'micromark-util-sanitize-uri'
const own = {}.hasOwnProperty
/** @type {Options} */
const emptyOptions = {}
const emptyOptions = {};

@@ -132,7 +25,3 @@ /**

export function defaultBackLabel(referenceIndex, rereferenceIndex) {
return (
'Back to reference ' +
(referenceIndex + 1) +
(rereferenceIndex > 1 ? '-' + rereferenceIndex : '')
)
return 'Back to reference ' + (referenceIndex + 1) + (rereferenceIndex > 1 ? '-' + rereferenceIndex : '');
}

@@ -151,25 +40,19 @@

export function gfmFootnoteHtml(options) {
const config = options || emptyOptions
const label = config.label || 'Footnotes'
const labelTagName = config.labelTagName || 'h2'
const labelAttributes =
config.labelAttributes === null || config.labelAttributes === undefined
? 'class="sr-only"'
: config.labelAttributes
const backLabel = config.backLabel || defaultBackLabel
const clobberPrefix =
config.clobberPrefix === null || config.clobberPrefix === undefined
? 'user-content-'
: config.clobberPrefix
const config = options || emptyOptions;
const label = config.label || 'Footnotes';
const labelTagName = config.labelTagName || 'h2';
const labelAttributes = config.labelAttributes === null || config.labelAttributes === undefined ? 'class="sr-only"' : config.labelAttributes;
const backLabel = config.backLabel || defaultBackLabel;
const clobberPrefix = config.clobberPrefix === null || config.clobberPrefix === undefined ? 'user-content-' : config.clobberPrefix;
return {
enter: {
gfmFootnoteDefinition() {
const stack = this.getData('tightStack')
stack.push(false)
const stack = this.getData('tightStack');
stack.push(false);
},
gfmFootnoteDefinitionLabelString() {
this.buffer()
this.buffer();
},
gfmFootnoteCallString() {
this.buffer()
this.buffer();
}

@@ -179,135 +62,96 @@ },

gfmFootnoteDefinition() {
let definitions = this.getData('gfmFootnoteDefinitions')
const footnoteStack = this.getData('gfmFootnoteDefinitionStack')
const tightStack = this.getData('tightStack')
const current = footnoteStack.pop()
const value = this.resume()
let definitions = this.getData('gfmFootnoteDefinitions');
const footnoteStack = this.getData('gfmFootnoteDefinitionStack');
const tightStack = this.getData('tightStack');
const current = footnoteStack.pop();
const value = this.resume();
if (!definitions) {
this.setData('gfmFootnoteDefinitions', (definitions = {}))
this.setData('gfmFootnoteDefinitions', definitions = {});
}
if (!own.call(definitions, current)) definitions[current] = value
tightStack.pop()
this.setData('slurpOneLineEnding', true)
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
// an empty list item.
this.setData('lastWasTag')
this.setData('lastWasTag');
},
gfmFootnoteDefinitionLabelString(token) {
let footnoteStack = this.getData('gfmFootnoteDefinitionStack')
let footnoteStack = this.getData('gfmFootnoteDefinitionStack');
if (!footnoteStack) {
this.setData('gfmFootnoteDefinitionStack', (footnoteStack = []))
this.setData('gfmFootnoteDefinitionStack', footnoteStack = []);
}
footnoteStack.push(normalizeIdentifier(this.sliceSerialize(token)))
this.resume() // Drop the label.
this.buffer() // Get ready for a value.
footnoteStack.push(normalizeIdentifier(this.sliceSerialize(token)));
this.resume(); // Drop the label.
this.buffer(); // Get ready for a value.
},
gfmFootnoteCallString(token) {
let calls = this.getData('gfmFootnoteCallOrder')
let counts = this.getData('gfmFootnoteCallCounts')
const id = normalizeIdentifier(this.sliceSerialize(token))
let calls = this.getData('gfmFootnoteCallOrder');
let counts = this.getData('gfmFootnoteCallCounts');
const id = normalizeIdentifier(this.sliceSerialize(token));
/** @type {number} */
let counter
this.resume()
if (!calls) this.setData('gfmFootnoteCallOrder', (calls = []))
if (!counts) this.setData('gfmFootnoteCallCounts', (counts = {}))
const index = calls.indexOf(id)
const safeId = sanitizeUri(id.toLowerCase())
let counter;
this.resume();
if (!calls) this.setData('gfmFootnoteCallOrder', calls = []);
if (!counts) this.setData('gfmFootnoteCallCounts', counts = {});
const index = calls.indexOf(id);
const safeId = sanitizeUri(id.toLowerCase());
if (index === -1) {
calls.push(id)
counts[id] = 1
counter = calls.length
calls.push(id);
counts[id] = 1;
counter = calls.length;
} else {
counts[id]++
counter = index + 1
counts[id]++;
counter = index + 1;
}
const reuseCounter = counts[id]
this.tag(
'<sup><a href="#' +
clobberPrefix +
'fn-' +
safeId +
'" id="' +
clobberPrefix +
'fnref-' +
safeId +
(reuseCounter > 1 ? '-' + reuseCounter : '') +
'" data-footnote-ref="" aria-describedby="footnote-label">' +
String(counter) +
'</a></sup>'
)
const reuseCounter = counts[id];
this.tag('<sup><a href="#' + clobberPrefix + 'fn-' + safeId + '" id="' + clobberPrefix + 'fnref-' + safeId + (reuseCounter > 1 ? '-' + reuseCounter : '') + '" data-footnote-ref="" aria-describedby="footnote-label">' + String(counter) + '</a></sup>');
},
null() {
const calls = this.getData('gfmFootnoteCallOrder') || []
const counts = this.getData('gfmFootnoteCallCounts') || {}
const definitions = this.getData('gfmFootnoteDefinitions') || {}
let index = -1
const calls = this.getData('gfmFootnoteCallOrder') || [];
const counts = this.getData('gfmFootnoteCallCounts') || {};
const definitions = this.getData('gfmFootnoteDefinitions') || {};
let index = -1;
if (calls.length > 0) {
this.lineEndingIfNeeded()
this.tag(
'<section data-footnotes="" class="footnotes"><' +
labelTagName +
' id="footnote-label"' +
(labelAttributes ? ' ' + labelAttributes : '') +
'>'
)
this.raw(this.encode(label))
this.tag('</' + labelTagName + '>')
this.lineEndingIfNeeded()
this.tag('<ol>')
this.lineEndingIfNeeded();
this.tag('<section data-footnotes="" class="footnotes"><' + labelTagName + ' id="footnote-label"' + (labelAttributes ? ' ' + labelAttributes : '') + '>');
this.raw(this.encode(label));
this.tag('</' + labelTagName + '>');
this.lineEndingIfNeeded();
this.tag('<ol>');
}
while (++index < calls.length) {
// Called definitions are always defined.
const id = calls[index]
const safeId = sanitizeUri(id.toLowerCase())
let referenceIndex = 0
const id = calls[index];
const safeId = sanitizeUri(id.toLowerCase());
let referenceIndex = 0;
/** @type {Array<string>} */
const references = []
const references = [];
while (++referenceIndex <= counts[id]) {
references.push(
'<a href="#' +
clobberPrefix +
'fnref-' +
safeId +
(referenceIndex > 1 ? '-' + referenceIndex : '') +
'" data-footnote-backref="" aria-label="' +
this.encode(
typeof backLabel === 'string'
? backLabel
: backLabel(index, referenceIndex)
) +
'" class="data-footnote-backref">↩' +
(referenceIndex > 1
? '<sup>' + referenceIndex + '</sup>'
: '') +
'</a>'
)
references.push('<a href="#' + clobberPrefix + 'fnref-' + safeId + (referenceIndex > 1 ? '-' + referenceIndex : '') + '" data-footnote-backref="" aria-label="' + this.encode(typeof backLabel === 'string' ? backLabel : backLabel(index, referenceIndex)) + '" class="data-footnote-backref">↩' + (referenceIndex > 1 ? '<sup>' + referenceIndex + '</sup>' : '') + '</a>');
}
const reference = references.join(' ')
let injected = false
this.lineEndingIfNeeded()
this.tag('<li id="' + clobberPrefix + 'fn-' + safeId + '">')
this.lineEndingIfNeeded()
this.tag(
definitions[id].replace(/<\/p>(?:\r?\n|\r)?$/, function ($0) {
injected = true
return ' ' + reference + $0
})
)
const reference = references.join(' ');
let injected = false;
this.lineEndingIfNeeded();
this.tag('<li id="' + clobberPrefix + 'fn-' + safeId + '">');
this.lineEndingIfNeeded();
this.tag(definitions[id].replace(/<\/p>(?:\r?\n|\r)?$/, function ($0) {
injected = true;
return ' ' + reference + $0;
}));
if (!injected) {
this.lineEndingIfNeeded()
this.tag(reference)
this.lineEndingIfNeeded();
this.tag(reference);
}
this.lineEndingIfNeeded()
this.tag('</li>')
this.lineEndingIfNeeded();
this.tag('</li>');
}
if (calls.length > 0) {
this.lineEndingIfNeeded()
this.tag('</ol>')
this.lineEndingIfNeeded()
this.tag('</section>')
this.lineEndingIfNeeded();
this.tag('</ol>');
this.lineEndingIfNeeded();
this.tag('</section>');
}
}
}
}
}
};
}

@@ -8,10 +8,3 @@ /**

*/
export function gfmFootnote(): Extension
export type Event = import('micromark-util-types').Event
export type Exiter = import('micromark-util-types').Exiter
export type Extension = import('micromark-util-types').Extension
export type Resolver = import('micromark-util-types').Resolver
export type State = import('micromark-util-types').State
export type Token = import('micromark-util-types').Token
export type TokenizeContext = import('micromark-util-types').TokenizeContext
export type Tokenizer = import('micromark-util-types').Tokenizer
export function gfmFootnote(): Extension;
import type { Extension } from 'micromark-util-types';
/**
* @typedef {import('micromark-util-types').Event} Event
* @typedef {import('micromark-util-types').Exiter} Exiter
* @typedef {import('micromark-util-types').Extension} Extension
* @typedef {import('micromark-util-types').Resolver} Resolver
* @typedef {import('micromark-util-types').State} State
* @typedef {import('micromark-util-types').Token} Token
* @typedef {import('micromark-util-types').TokenizeContext} TokenizeContext
* @typedef {import('micromark-util-types').Tokenizer} Tokenizer
* @import {Event, Exiter, Extension, Resolver, State, Token, TokenizeContext, Tokenizer} from 'micromark-util-types'
*/
import {blankLine} from 'micromark-core-commonmark'
import {factorySpace} from 'micromark-factory-space'
import {markdownLineEndingOrSpace} from 'micromark-util-character'
import {normalizeIdentifier} from 'micromark-util-normalize-identifier'
import { blankLine } from 'micromark-core-commonmark';
import { factorySpace } from 'micromark-factory-space';
import { markdownLineEndingOrSpace } from 'micromark-util-character';
import { normalizeIdentifier } from 'micromark-util-normalize-identifier';
const indent = {
tokenize: tokenizeIndent,
partial: true
}
};

@@ -39,2 +32,3 @@ // To do: micromark should support a `_hiddenGfmFootnoteSupport`, which only

[91]: {
name: 'gfmFootnoteDefinition',
tokenize: tokenizeDefinitionStart,

@@ -49,5 +43,7 @@ continuation: {

[91]: {
name: 'gfmFootnoteCall',
tokenize: tokenizeGfmFootnoteCall
},
[93]: {
name: 'gfmPotentialFootnoteCall',
add: 'after',

@@ -58,3 +54,3 @@ tokenize: tokenizePotentialGfmFootnoteCall,

}
}
};
}

@@ -68,28 +64,22 @@

function tokenizePotentialGfmFootnoteCall(effects, ok, nok) {
const self = this
let index = self.events.length
const defined = self.parser.gfmFootnotes || (self.parser.gfmFootnotes = [])
const self = this;
let index = self.events.length;
const defined = self.parser.gfmFootnotes || (self.parser.gfmFootnotes = []);
/** @type {Token} */
let labelStart
let labelStart;
// Find an opening.
while (index--) {
const token = self.events[index][1]
if (token.type === 'labelImage') {
labelStart = token
break
const token = self.events[index][1];
if (token.type === "labelImage") {
labelStart = token;
break;
}
// Exit if we’ve walked far enough.
if (
token.type === 'gfmFootnoteCall' ||
token.type === 'labelLink' ||
token.type === 'label' ||
token.type === 'image' ||
token.type === 'link'
) {
break
if (token.type === 'gfmFootnoteCall' || token.type === "labelLink" || token.type === "label" || token.type === "image" || token.type === "link") {
break;
}
}
return start
return start;

@@ -101,17 +91,15 @@ /**

if (!labelStart || !labelStart._balanced) {
return nok(code)
return nok(code);
}
const id = normalizeIdentifier(
self.sliceSerialize({
start: labelStart.end,
end: self.now()
})
)
const id = normalizeIdentifier(self.sliceSerialize({
start: labelStart.end,
end: self.now()
}));
if (id.codePointAt(0) !== 94 || !defined.includes(id.slice(1))) {
return nok(code)
return nok(code);
}
effects.enter('gfmFootnoteCallLabelMarker')
effects.consume(code)
effects.exit('gfmFootnoteCallLabelMarker')
return ok(code)
effects.enter('gfmFootnoteCallLabelMarker');
effects.consume(code);
effects.exit('gfmFootnoteCallLabelMarker');
return ok(code);
}

@@ -123,19 +111,16 @@ }

function resolveToPotentialGfmFootnoteCall(events, context) {
let index = events.length
let index = events.length;
/** @type {Token | undefined} */
let labelStart
let labelStart;
// Find an opening.
while (index--) {
if (
events[index][1].type === 'labelImage' &&
events[index][0] === 'enter'
) {
labelStart = events[index][1]
break
if (events[index][1].type === "labelImage" && events[index][0] === 'enter') {
labelStart = events[index][1];
break;
}
}
// Change the `labelImageMarker` to a `data`.
events[index + 1][1].type = 'data'
events[index + 3][1].type = 'gfmFootnoteCallLabelMarker'
events[index + 1][1].type = "data";
events[index + 3][1].type = 'gfmFootnoteCallLabelMarker';

@@ -148,3 +133,3 @@ // The whole (without `!`):

end: Object.assign({}, events[events.length - 1][1].end)
}
};
// The `^` marker

@@ -156,7 +141,7 @@ /** @type {Token} */

end: Object.assign({}, events[index + 3][1].end)
}
};
// Increment the end 1 character.
marker.end.column++
marker.end.offset++
marker.end._bufferIndex++
marker.end.column++;
marker.end.offset++;
marker.end._bufferIndex++;
/** @type {Token} */

@@ -167,35 +152,25 @@ const string = {

end: Object.assign({}, events[events.length - 1][1].start)
}
};
/** @type {Token} */
const chunk = {
type: 'chunkString',
type: "chunkString",
contentType: 'string',
start: Object.assign({}, string.start),
end: Object.assign({}, string.end)
}
};
/** @type {Array<Event>} */
const replacement = [
// Take the `labelImageMarker` (now `data`, the `!`)
events[index + 1],
events[index + 2],
['enter', call, context],
// The `[`
events[index + 3],
events[index + 4],
// The `^`.
['enter', marker, context],
['exit', marker, context],
// Everything in between.
['enter', string, context],
['enter', chunk, context],
['exit', chunk, context],
['exit', string, context],
// The ending (`]`, properly parsed and labelled).
events[events.length - 2],
events[events.length - 1],
['exit', call, context]
]
events.splice(index, events.length - index + 1, ...replacement)
return events
// Take the `labelImageMarker` (now `data`, the `!`)
events[index + 1], events[index + 2], ['enter', call, context],
// The `[`
events[index + 3], events[index + 4],
// The `^`.
['enter', marker, context], ['exit', marker, context],
// Everything in between.
['enter', string, context], ['enter', chunk, context], ['exit', chunk, context], ['exit', string, context],
// The ending (`]`, properly parsed and labelled).
events[events.length - 2], events[events.length - 1], ['exit', call, context]];
events.splice(index, events.length - index + 1, ...replacement);
return events;
}

@@ -208,7 +183,7 @@

function tokenizeGfmFootnoteCall(effects, ok, nok) {
const self = this
const defined = self.parser.gfmFootnotes || (self.parser.gfmFootnotes = [])
let size = 0
const self = this;
const defined = self.parser.gfmFootnotes || (self.parser.gfmFootnotes = []);
let size = 0;
/** @type {boolean} */
let data
let data;

@@ -220,3 +195,3 @@ // Note: the implementation of `markdown-rs` is different, because it houses

// needed for labels.
return start
return start;

@@ -234,7 +209,7 @@ /**

function start(code) {
effects.enter('gfmFootnoteCall')
effects.enter('gfmFootnoteCallLabelMarker')
effects.consume(code)
effects.exit('gfmFootnoteCallLabelMarker')
return callStart
effects.enter('gfmFootnoteCall');
effects.enter('gfmFootnoteCallLabelMarker');
effects.consume(code);
effects.exit('gfmFootnoteCallLabelMarker');
return callStart;
}

@@ -253,9 +228,9 @@

function callStart(code) {
if (code !== 94) return nok(code)
effects.enter('gfmFootnoteCallMarker')
effects.consume(code)
effects.exit('gfmFootnoteCallMarker')
effects.enter('gfmFootnoteCallString')
effects.enter('chunkString').contentType = 'string'
return callData
if (code !== 94) return nok(code);
effects.enter('gfmFootnoteCallMarker');
effects.consume(code);
effects.exit('gfmFootnoteCallMarker');
effects.enter('gfmFootnoteCallString');
effects.enter('chunkString').contentType = 'string';
return callData;
}

@@ -275,32 +250,29 @@

if (
// Too long.
size > 999 ||
// Closing brace with nothing.
(code === 93 && !data) ||
// Space or tab is not supported by GFM for some reason.
// `\n` and `[` not being supported makes sense.
code === null ||
code === 91 ||
markdownLineEndingOrSpace(code)
) {
return nok(code)
// Too long.
size > 999 ||
// Closing brace with nothing.
code === 93 && !data ||
// Space or tab is not supported by GFM for some reason.
// `\n` and `[` not being supported makes sense.
code === null || code === 91 || markdownLineEndingOrSpace(code)) {
return nok(code);
}
if (code === 93) {
effects.exit('chunkString')
const token = effects.exit('gfmFootnoteCallString')
effects.exit('chunkString');
const token = effects.exit('gfmFootnoteCallString');
if (!defined.includes(normalizeIdentifier(self.sliceSerialize(token)))) {
return nok(code)
return nok(code);
}
effects.enter('gfmFootnoteCallLabelMarker')
effects.consume(code)
effects.exit('gfmFootnoteCallLabelMarker')
effects.exit('gfmFootnoteCall')
return ok
effects.enter('gfmFootnoteCallLabelMarker');
effects.consume(code);
effects.exit('gfmFootnoteCallLabelMarker');
effects.exit('gfmFootnoteCall');
return ok;
}
if (!markdownLineEndingOrSpace(code)) {
data = true
data = true;
}
size++
effects.consume(code)
return code === 92 ? callEscape : callData
size++;
effects.consume(code);
return code === 92 ? callEscape : callData;
}

@@ -320,7 +292,7 @@

if (code === 91 || code === 92 || code === 93) {
effects.consume(code)
size++
return callData
effects.consume(code);
size++;
return callData;
}
return callData(code)
return callData(code);
}

@@ -334,10 +306,10 @@ }

function tokenizeDefinitionStart(effects, ok, nok) {
const self = this
const defined = self.parser.gfmFootnotes || (self.parser.gfmFootnotes = [])
const self = this;
const defined = self.parser.gfmFootnotes || (self.parser.gfmFootnotes = []);
/** @type {string} */
let identifier
let size = 0
let identifier;
let size = 0;
/** @type {boolean | undefined} */
let data
return start
let data;
return start;

@@ -355,8 +327,8 @@ /**

function start(code) {
effects.enter('gfmFootnoteDefinition')._container = true
effects.enter('gfmFootnoteDefinitionLabel')
effects.enter('gfmFootnoteDefinitionLabelMarker')
effects.consume(code)
effects.exit('gfmFootnoteDefinitionLabelMarker')
return labelAtMarker
effects.enter('gfmFootnoteDefinition')._container = true;
effects.enter('gfmFootnoteDefinitionLabel');
effects.enter('gfmFootnoteDefinitionLabelMarker');
effects.consume(code);
effects.exit('gfmFootnoteDefinitionLabelMarker');
return labelAtMarker;
}

@@ -376,10 +348,10 @@

if (code === 94) {
effects.enter('gfmFootnoteDefinitionMarker')
effects.consume(code)
effects.exit('gfmFootnoteDefinitionMarker')
effects.enter('gfmFootnoteDefinitionLabelString')
effects.enter('chunkString').contentType = 'string'
return labelInside
effects.enter('gfmFootnoteDefinitionMarker');
effects.consume(code);
effects.exit('gfmFootnoteDefinitionMarker');
effects.enter('gfmFootnoteDefinitionLabelString');
effects.enter('chunkString').contentType = 'string';
return labelInside;
}
return nok(code)
return nok(code);
}

@@ -402,30 +374,27 @@

if (
// Too long.
size > 999 ||
// Closing brace with nothing.
(code === 93 && !data) ||
// Space or tab is not supported by GFM for some reason.
// `\n` and `[` not being supported makes sense.
code === null ||
code === 91 ||
markdownLineEndingOrSpace(code)
) {
return nok(code)
// Too long.
size > 999 ||
// Closing brace with nothing.
code === 93 && !data ||
// Space or tab is not supported by GFM for some reason.
// `\n` and `[` not being supported makes sense.
code === null || code === 91 || markdownLineEndingOrSpace(code)) {
return nok(code);
}
if (code === 93) {
effects.exit('chunkString')
const token = effects.exit('gfmFootnoteDefinitionLabelString')
identifier = normalizeIdentifier(self.sliceSerialize(token))
effects.enter('gfmFootnoteDefinitionLabelMarker')
effects.consume(code)
effects.exit('gfmFootnoteDefinitionLabelMarker')
effects.exit('gfmFootnoteDefinitionLabel')
return labelAfter
effects.exit('chunkString');
const token = effects.exit('gfmFootnoteDefinitionLabelString');
identifier = normalizeIdentifier(self.sliceSerialize(token));
effects.enter('gfmFootnoteDefinitionLabelMarker');
effects.consume(code);
effects.exit('gfmFootnoteDefinitionLabelMarker');
effects.exit('gfmFootnoteDefinitionLabel');
return labelAfter;
}
if (!markdownLineEndingOrSpace(code)) {
data = true
data = true;
}
size++
effects.consume(code)
return code === 92 ? labelEscape : labelInside
size++;
effects.consume(code);
return code === 92 ? labelEscape : labelInside;
}

@@ -448,7 +417,7 @@

if (code === 91 || code === 92 || code === 93) {
effects.consume(code)
size++
return labelInside
effects.consume(code);
size++;
return labelInside;
}
return labelInside(code)
return labelInside(code);
}

@@ -468,7 +437,7 @@

if (code === 58) {
effects.enter('definitionMarker')
effects.consume(code)
effects.exit('definitionMarker')
effects.enter('definitionMarker');
effects.consume(code);
effects.exit('definitionMarker');
if (!defined.includes(identifier)) {
defined.push(identifier)
defined.push(identifier);
}

@@ -479,9 +448,5 @@

// No space is also fine, just like a block quote marker.
return factorySpace(
effects,
whitespaceAfter,
'gfmFootnoteDefinitionWhitespace'
)
return factorySpace(effects, whitespaceAfter, 'gfmFootnoteDefinitionWhitespace');
}
return nok(code)
return nok(code);
}

@@ -501,3 +466,3 @@

// `markdown-rs` has a wrapping token for the prefix that is closed here.
return ok(code)
return ok(code);
}

@@ -520,3 +485,3 @@ }

// Either a blank line, which is okay, or an indented thing.
return effects.check(blankLine, ok, effects.attempt(indent, ok, nok))
return effects.check(blankLine, ok, effects.attempt(indent, ok, nok));
}

@@ -526,3 +491,3 @@

function gfmFootnoteDefinitionEnd(effects) {
effects.exit('gfmFootnoteDefinition')
effects.exit('gfmFootnoteDefinition');
}

@@ -535,9 +500,4 @@

function tokenizeIndent(effects, ok, nok) {
const self = this
return factorySpace(
effects,
afterPrefix,
'gfmFootnoteDefinitionIndent',
4 + 1
)
const self = this;
return factorySpace(effects, afterPrefix, 'gfmFootnoteDefinitionIndent', 4 + 1);

@@ -548,9 +508,5 @@ /**

function afterPrefix(code) {
const tail = self.events[self.events.length - 1]
return tail &&
tail[1].type === 'gfmFootnoteDefinitionIndent' &&
tail[2].sliceSerialize(tail[1], true).length === 4
? ok(code)
: nok(code)
const tail = self.events[self.events.length - 1];
return tail && tail[1].type === 'gfmFootnoteDefinitionIndent' && tail[2].sliceSerialize(tail[1], true).length === 4 ? ok(code) : nok(code);
}
}
}
{
"name": "micromark-extension-gfm-footnote",
"version": "2.0.0",
"version": "2.1.0",
"description": "micromark extension to support GFM footnotes",

@@ -50,12 +50,12 @@ "license": "MIT",

"@types/node": "^20.0.0",
"c8": "^8.0.0",
"c8": "^10.0.0",
"create-gfm-fixtures": "^1.0.0",
"micromark": "^4.0.0",
"micromark-build": "^2.0.0",
"prettier": "^2.0.0",
"remark-cli": "^11.0.0",
"remark-preset-wooorm": "^9.0.0",
"prettier": "^3.0.0",
"remark-cli": "^12.0.0",
"remark-preset-wooorm": "^10.0.0",
"type-coverage": "^2.0.0",
"typescript": "^5.0.0",
"xo": "^0.54.0"
"xo": "^0.58.0"
},

@@ -65,3 +65,3 @@ "scripts": {

"build": "tsc --build --clean && tsc --build && type-coverage && micromark-build",
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix",
"format": "remark . -qfo && prettier . -w --log-level warn && xo --fix",
"test-api-prod": "node --conditions production test/index.js",

@@ -95,3 +95,6 @@ "test-api-dev": "node --conditions development test/index.js",

"rules": {
"unicorn/no-this-assignment": "off"
"logical-assignment-operators": "off",
"unicorn/no-this-assignment": "off",
"unicorn/prefer-at": "off",
"unicorn/prefer-string-replace-all": "off"
},

@@ -101,6 +104,21 @@ "overrides": [

"files": [
"**/*.ts"
"**/*.d.ts"
],
"rules": {
"@typescript-eslint/consistent-type-definitions": 0
"@typescript-eslint/array-type": [
"error",
{
"default": "generic"
}
],
"@typescript-eslint/ban-types": [
"error",
{
"extendDefaults": true
}
],
"@typescript-eslint/consistent-type-definitions": [
"error",
"interface"
]
}

@@ -107,0 +125,0 @@ },

@@ -15,23 +15,23 @@ # micromark-extension-gfm-footnote

* [What is this?](#what-is-this)
* [When to use this](#when-to-use-this)
* [Install](#install)
* [Use](#use)
* [API](#api)
* [`defaultBackLabel(referenceIndex, rereferenceIndex)`](#defaultbacklabelreferenceindex-rereferenceindex)
* [`gfmFootnote()`](#gfmfootnote)
* [`gfmFootnoteHtml(options?)`](#gfmfootnotehtmloptions)
* [`BackLabelTemplate`](#backlabeltemplate)
* [`HtmlOptions`](#htmloptions)
* [Bugs](#bugs)
* [Authoring](#authoring)
* [HTML](#html)
* [CSS](#css)
* [Syntax](#syntax)
* [Types](#types)
* [Compatibility](#compatibility)
* [Security](#security)
* [Related](#related)
* [Contribute](#contribute)
* [License](#license)
* [What is this?](#what-is-this)
* [When to use this](#when-to-use-this)
* [Install](#install)
* [Use](#use)
* [API](#api)
* [`defaultBackLabel(referenceIndex, rereferenceIndex)`](#defaultbacklabelreferenceindex-rereferenceindex)
* [`gfmFootnote()`](#gfmfootnote)
* [`gfmFootnoteHtml(options?)`](#gfmfootnotehtmloptions)
* [`BackLabelTemplate`](#backlabeltemplate)
* [`HtmlOptions`](#htmloptions)
* [Bugs](#bugs)
* [Authoring](#authoring)
* [HTML](#html)
* [CSS](#css)
* [Syntax](#syntax)
* [Types](#types)
* [Compatibility](#compatibility)
* [Security](#security)
* [Related](#related)
* [Contribute](#contribute)
* [License](#license)

@@ -184,4 +184,4 @@ ## What is this?

* `options` ([`HtmlOptions`][api-html-options], optional)
— configuration
* `options` ([`HtmlOptions`][api-html-options], optional)
— configuration

@@ -209,16 +209,16 @@ ###### Returns

* `0` and `0` for the backreference from `things about micromark` to
`alpha`, as it is the first used definition, and the first call to it
* `0` and `1` for the backreference from `things about micromark` to
`bravo`, as it is the first used definition, and the second call to it
* `1` and `0` for the backreference from `things about remark` to
`charlie`, as it is the second used definition
* `0` and `0` for the backreference from `things about micromark` to
`alpha`, as it is the first used definition, and the first call to it
* `0` and `1` for the backreference from `things about micromark` to
`bravo`, as it is the first used definition, and the second call to it
* `1` and `0` for the backreference from `things about remark` to
`charlie`, as it is the second used definition
###### Parameters
* `referenceIndex` (`number`)
— index of the definition in the order that they are first referenced,
0-indexed
* `rereferenceIndex` (`number`)
— index of calls to the same definition, 0-indexed
* `referenceIndex` (`number`)
— index of the definition in the order that they are first referenced,
0-indexed
* `rereferenceIndex` (`number`)
— index of calls to the same definition, 0-indexed

@@ -312,25 +312,25 @@ ###### Returns

* [Footnote reference call identifiers are trimmed, but definition
identifiers aren’t](https://github.com/github/cmark-gfm/issues/237)\
— initial and final whitespace in labels causes them not to match
* [Footnotes are matched case-insensitive, but links keep their casing,
breaking them](https://github.com/github/cmark-gfm/issues/239)\
— using uppercase (or any character that will be percent encoded) in
identifiers breaks links
* [Colons in footnotes generate links w/o
`href`](https://github.com/github/cmark-gfm/issues/250)\
— colons in identifiers generate broken links
* [Character escape of `]` does not work in footnote
identifiers](https://github.com/github/cmark-gfm/issues/240)\
— some character escapes don’t work
* [Footnotes in links are
broken](https://github.com/github/cmark-gfm/issues/249)\
— while `CommonMark` prevents links in links, GitHub does not prevent
footnotes (which turn into links) in links
* [Footnote-like brackets around image, break that
image](https://github.com/github/cmark-gfm/issues/275)\
— images can’t be used in what looks like a footnote call
* [GFM footnotes: line ending in footnote definition label causes text to
disappear](https://github.com/github/cmark-gfm/issues/282)\
— line endings in footnote definitions cause text to disappear
* [Footnote reference call identifiers are trimmed, but definition
identifiers aren’t](https://github.com/github/cmark-gfm/issues/237)\
— initial and final whitespace in labels causes them not to match
* [Footnotes are matched case-insensitive, but links keep their casing,
breaking them](https://github.com/github/cmark-gfm/issues/239)\
— using uppercase (or any character that will be percent encoded) in
identifiers breaks links
* [Colons in footnotes generate links w/o
`href`](https://github.com/github/cmark-gfm/issues/250)\
— colons in identifiers generate broken links
* [Character escape of `]` does not work in footnote
identifiers](https://github.com/github/cmark-gfm/issues/240)\
— some character escapes don’t work
* [Footnotes in links are
broken](https://github.com/github/cmark-gfm/issues/249)\
— while `CommonMark` prevents links in links, GitHub does not prevent
footnotes (which turn into links) in links
* [Footnote-like brackets around image, break that
image](https://github.com/github/cmark-gfm/issues/275)\
— images can’t be used in what looks like a footnote call
* [GFM footnotes: line ending in footnote definition label causes text to
disappear](https://github.com/github/cmark-gfm/issues/282)\
— line endings in footnote definitions cause text to disappear

@@ -537,10 +537,10 @@ ## Authoring

* [`micromark-extension-gfm`][micromark-extension-gfm]
— support all of GFM
* [`mdast-util-gfm-footnote`][mdast-util-gfm-footnote]
— support all of GFM in mdast
* [`mdast-util-gfm`][mdast-util-gfm]
— support all of GFM in mdast
* [`remark-gfm`][remark-gfm]
— support all of GFM in remark
* [`micromark-extension-gfm`][micromark-extension-gfm]
— support all of GFM
* [`mdast-util-gfm-footnote`][mdast-util-gfm-footnote]
— support all of GFM in mdast
* [`mdast-util-gfm`][mdast-util-gfm]
— support all of GFM in mdast
* [`remark-gfm`][remark-gfm]
— support all of GFM in remark

@@ -547,0 +547,0 @@ ## Contribute

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc