micromark-extension-mdx-expression
Advanced tools
Comparing version 2.0.0 to 3.0.0
@@ -10,9 +10,9 @@ /** | ||
*/ | ||
export function mdxExpression(options?: Options | null | undefined): Extension | ||
export type Acorn = import('micromark-util-events-to-acorn').Acorn | ||
export type AcornOptions = import('micromark-util-events-to-acorn').AcornOptions | ||
export type Extension = import('micromark-util-types').Extension | ||
export type State = import('micromark-util-types').State | ||
export type TokenizeContext = import('micromark-util-types').TokenizeContext | ||
export type Tokenizer = import('micromark-util-types').Tokenizer | ||
export function mdxExpression(options?: Options | null | undefined): Extension; | ||
export type Acorn = import('micromark-util-events-to-acorn').Acorn; | ||
export type AcornOptions = import('micromark-util-events-to-acorn').AcornOptions; | ||
export type Extension = import('micromark-util-types').Extension; | ||
export type State = import('micromark-util-types').State; | ||
export type TokenizeContext = import('micromark-util-types').TokenizeContext; | ||
export type Tokenizer = import('micromark-util-types').Tokenizer; | ||
/** | ||
@@ -22,30 +22,30 @@ * Configuration (optional). | ||
export type Options = { | ||
/** | ||
* Acorn parser to use (optional). | ||
*/ | ||
acorn?: Acorn | null | undefined | ||
/** | ||
* Configuration for acorn (default: `{ecmaVersion: 2020, locations: true, | ||
* sourceType: 'module'}`). | ||
* | ||
* All fields except `locations` can be set. | ||
*/ | ||
acornOptions?: AcornOptions | null | undefined | ||
/** | ||
* Whether to add `estree` fields to tokens with results from acorn (default: | ||
* `false`). | ||
*/ | ||
addResult?: boolean | null | undefined | ||
/** | ||
* Undocumented option to parse only a spread (used by | ||
* `micromark-extension-mdx-jsx` to parse spread attributes) (default: | ||
* `false`). | ||
*/ | ||
spread?: boolean | null | undefined | ||
/** | ||
* Undocumented option to disallow empty attributes (used by | ||
* `micromark-extension-mdx-jsx` to prohobit empty attribute values) | ||
* (default: `false`). | ||
*/ | ||
allowEmpty?: boolean | null | undefined | ||
} | ||
/** | ||
* Acorn parser to use (optional). | ||
*/ | ||
acorn?: Acorn | null | undefined; | ||
/** | ||
* Configuration for acorn (default: `{ecmaVersion: 2024, locations: true, | ||
* sourceType: 'module'}`). | ||
* | ||
* All fields except `locations` can be set. | ||
*/ | ||
acornOptions?: AcornOptions | null | undefined; | ||
/** | ||
* Whether to add `estree` fields to tokens with results from acorn (default: | ||
* `false`). | ||
*/ | ||
addResult?: boolean | null | undefined; | ||
/** | ||
* Undocumented option to parse only a spread (used by | ||
* `micromark-extension-mdx-jsx` to parse spread attributes) (default: | ||
* `false`). | ||
*/ | ||
spread?: boolean | null | undefined; | ||
/** | ||
* Undocumented option to disallow empty attributes (used by | ||
* `micromark-extension-mdx-jsx` to prohobit empty attribute values) | ||
* (default: `false`). | ||
*/ | ||
allowEmpty?: boolean | null | undefined; | ||
}; |
@@ -16,3 +16,3 @@ /** | ||
* @property {AcornOptions | null | undefined} [acornOptions] | ||
* Configuration for acorn (default: `{ecmaVersion: 2020, locations: true, | ||
* Configuration for acorn (default: `{ecmaVersion: 2024, locations: true, | ||
* sourceType: 'module'}`). | ||
@@ -75,3 +75,3 @@ * | ||
acornOptions = Object.assign( | ||
{ecmaVersion: 2020, sourceType: 'module'}, | ||
{ecmaVersion: 2024, sourceType: 'module'}, | ||
options_.acornOptions | ||
@@ -85,5 +85,14 @@ ) | ||
flow: { | ||
[codes.leftCurlyBrace]: {tokenize: tokenizeFlowExpression, concrete: true} | ||
[codes.leftCurlyBrace]: { | ||
name: 'mdxFlowExpression', | ||
tokenize: tokenizeFlowExpression, | ||
concrete: true | ||
} | ||
}, | ||
text: {[codes.leftCurlyBrace]: {tokenize: tokenizeTextExpression}} | ||
text: { | ||
[codes.leftCurlyBrace]: { | ||
name: 'mdxTextExpression', | ||
tokenize: tokenizeTextExpression | ||
} | ||
} | ||
} | ||
@@ -177,2 +186,41 @@ | ||
function end(code) { | ||
// We want to allow tags directly after expressions. | ||
// | ||
// This case is useful: | ||
// | ||
// ```mdx | ||
// <a>{b}</a> | ||
// ``` | ||
// | ||
// This case is not (very?) useful: | ||
// | ||
// ```mdx | ||
// {a}<b/> | ||
// ``` | ||
// | ||
// …but it would be tougher than needed to disallow. | ||
// | ||
// To allow that, here we call the flow construct of | ||
// `micromark-extension-mdx-jsx`, and there we call this one. | ||
// | ||
// It would introduce a cyclical interdependency if we test JSX and | ||
// expressions here. | ||
// Because the JSX extension already uses parts of this monorepo, we | ||
// instead test it there. | ||
const lessThanValue = self.parser.constructs.flow[codes.lessThan] | ||
const constructs = Array.isArray(lessThanValue) | ||
? lessThanValue | ||
: /* c8 ignore next 3 -- always a list when normalized. */ | ||
lessThanValue | ||
? [lessThanValue] | ||
: [] | ||
const jsxTag = constructs.find(function (d) { | ||
return d.name === 'mdxJsxFlowTag' | ||
}) | ||
/* c8 ignore next 3 -- this is tested in `micromark-extension-mdx-jsx` */ | ||
if (code === codes.lessThan && jsxTag) { | ||
return effects.attempt(jsxTag, end, nok)(code) | ||
} | ||
return code === codes.eof || markdownLineEnding(code) | ||
@@ -179,0 +227,0 @@ ? ok(code) |
@@ -5,2 +5,2 @@ /** | ||
export {mdxExpression} from './lib/syntax.js' | ||
export { mdxExpression } from './lib/syntax.js'; |
@@ -10,9 +10,9 @@ /** | ||
*/ | ||
export function mdxExpression(options?: Options | null | undefined): Extension | ||
export type Acorn = import('micromark-util-events-to-acorn').Acorn | ||
export type AcornOptions = import('micromark-util-events-to-acorn').AcornOptions | ||
export type Extension = import('micromark-util-types').Extension | ||
export type State = import('micromark-util-types').State | ||
export type TokenizeContext = import('micromark-util-types').TokenizeContext | ||
export type Tokenizer = import('micromark-util-types').Tokenizer | ||
export function mdxExpression(options?: Options | null | undefined): Extension; | ||
export type Acorn = import('micromark-util-events-to-acorn').Acorn; | ||
export type AcornOptions = import('micromark-util-events-to-acorn').AcornOptions; | ||
export type Extension = import('micromark-util-types').Extension; | ||
export type State = import('micromark-util-types').State; | ||
export type TokenizeContext = import('micromark-util-types').TokenizeContext; | ||
export type Tokenizer = import('micromark-util-types').Tokenizer; | ||
/** | ||
@@ -22,30 +22,30 @@ * Configuration (optional). | ||
export type Options = { | ||
/** | ||
* Acorn parser to use (optional). | ||
*/ | ||
acorn?: Acorn | null | undefined | ||
/** | ||
* Configuration for acorn (default: `{ecmaVersion: 2020, locations: true, | ||
* sourceType: 'module'}`). | ||
* | ||
* All fields except `locations` can be set. | ||
*/ | ||
acornOptions?: AcornOptions | null | undefined | ||
/** | ||
* Whether to add `estree` fields to tokens with results from acorn (default: | ||
* `false`). | ||
*/ | ||
addResult?: boolean | null | undefined | ||
/** | ||
* Undocumented option to parse only a spread (used by | ||
* `micromark-extension-mdx-jsx` to parse spread attributes) (default: | ||
* `false`). | ||
*/ | ||
spread?: boolean | null | undefined | ||
/** | ||
* Undocumented option to disallow empty attributes (used by | ||
* `micromark-extension-mdx-jsx` to prohobit empty attribute values) | ||
* (default: `false`). | ||
*/ | ||
allowEmpty?: boolean | null | undefined | ||
} | ||
/** | ||
* Acorn parser to use (optional). | ||
*/ | ||
acorn?: Acorn | null | undefined; | ||
/** | ||
* Configuration for acorn (default: `{ecmaVersion: 2024, locations: true, | ||
* sourceType: 'module'}`). | ||
* | ||
* All fields except `locations` can be set. | ||
*/ | ||
acornOptions?: AcornOptions | null | undefined; | ||
/** | ||
* Whether to add `estree` fields to tokens with results from acorn (default: | ||
* `false`). | ||
*/ | ||
addResult?: boolean | null | undefined; | ||
/** | ||
* Undocumented option to parse only a spread (used by | ||
* `micromark-extension-mdx-jsx` to parse spread attributes) (default: | ||
* `false`). | ||
*/ | ||
spread?: boolean | null | undefined; | ||
/** | ||
* Undocumented option to disallow empty attributes (used by | ||
* `micromark-extension-mdx-jsx` to prohobit empty attribute values) | ||
* (default: `false`). | ||
*/ | ||
allowEmpty?: boolean | null | undefined; | ||
}; |
@@ -16,3 +16,3 @@ /** | ||
* @property {AcornOptions | null | undefined} [acornOptions] | ||
* Configuration for acorn (default: `{ecmaVersion: 2020, locations: true, | ||
* Configuration for acorn (default: `{ecmaVersion: 2024, locations: true, | ||
* sourceType: 'module'}`). | ||
@@ -34,5 +34,5 @@ * | ||
import {factoryMdxExpression} from 'micromark-factory-mdx-expression' | ||
import {factorySpace} from 'micromark-factory-space' | ||
import {markdownLineEnding, markdownSpace} from 'micromark-util-character' | ||
import { factoryMdxExpression } from 'micromark-factory-mdx-expression'; | ||
import { factorySpace } from 'micromark-factory-space'; | ||
import { markdownLineEnding, markdownSpace } from 'micromark-util-character'; | ||
/** | ||
@@ -48,5 +48,5 @@ * Create an extension for `micromark` to enable MDX expression syntax. | ||
export function mdxExpression(options) { | ||
const options_ = options || {} | ||
const addResult = options_.addResult | ||
const acorn = options_.acorn | ||
const options_ = options || {}; | ||
const addResult = options_.addResult; | ||
const acorn = options_.acorn; | ||
// Hidden: `micromark-extension-mdx-jsx` supports expressions in tags, | ||
@@ -57,24 +57,19 @@ // and one of them is only “spread” elements. | ||
// to test that behavior. | ||
const spread = options_.spread | ||
let allowEmpty = options_.allowEmpty | ||
const spread = options_.spread; | ||
let allowEmpty = options_.allowEmpty; | ||
/** @type {AcornOptions} */ | ||
let acornOptions | ||
let acornOptions; | ||
if (allowEmpty === null || allowEmpty === undefined) { | ||
allowEmpty = true | ||
allowEmpty = true; | ||
} | ||
if (acorn) { | ||
if (!acorn.parseExpressionAt) { | ||
throw new Error( | ||
'Expected a proper `acorn` instance passed in as `options.acorn`' | ||
) | ||
throw new Error('Expected a proper `acorn` instance passed in as `options.acorn`'); | ||
} | ||
acornOptions = Object.assign( | ||
{ | ||
ecmaVersion: 2020, | ||
sourceType: 'module' | ||
}, | ||
options_.acornOptions | ||
) | ||
acornOptions = Object.assign({ | ||
ecmaVersion: 2024, | ||
sourceType: 'module' | ||
}, options_.acornOptions); | ||
} else if (options_.acornOptions || options_.addResult) { | ||
throw new Error('Expected an `acorn` instance passed in as `options.acorn`') | ||
throw new Error('Expected an `acorn` instance passed in as `options.acorn`'); | ||
} | ||
@@ -84,2 +79,3 @@ return { | ||
[123]: { | ||
name: 'mdxFlowExpression', | ||
tokenize: tokenizeFlowExpression, | ||
@@ -91,6 +87,7 @@ concrete: true | ||
[123]: { | ||
name: 'mdxTextExpression', | ||
tokenize: tokenizeTextExpression | ||
} | ||
} | ||
} | ||
}; | ||
@@ -109,4 +106,4 @@ /** | ||
function tokenizeFlowExpression(effects, ok, nok) { | ||
const self = this | ||
return start | ||
const self = this; | ||
return start; | ||
@@ -127,3 +124,3 @@ /** | ||
return before(code) | ||
return before(code); | ||
} | ||
@@ -142,15 +139,3 @@ | ||
function before(code) { | ||
return factoryMdxExpression.call( | ||
self, | ||
effects, | ||
after, | ||
'mdxFlowExpression', | ||
'mdxFlowExpressionMarker', | ||
'mdxFlowExpressionChunk', | ||
acorn, | ||
acornOptions, | ||
addResult, | ||
spread, | ||
allowEmpty | ||
)(code) | ||
return factoryMdxExpression.call(self, effects, after, 'mdxFlowExpression', 'mdxFlowExpressionMarker', 'mdxFlowExpressionChunk', acorn, acornOptions, addResult, spread, allowEmpty)(code); | ||
} | ||
@@ -169,5 +154,3 @@ | ||
function after(code) { | ||
return markdownSpace(code) | ||
? factorySpace(effects, end, 'whitespace')(code) | ||
: end(code) | ||
return markdownSpace(code) ? factorySpace(effects, end, "whitespace")(code) : end(code); | ||
} | ||
@@ -186,3 +169,37 @@ | ||
function end(code) { | ||
return code === null || markdownLineEnding(code) ? ok(code) : nok(code) | ||
// We want to allow tags directly after expressions. | ||
// | ||
// This case is useful: | ||
// | ||
// ```mdx | ||
// <a>{b}</a> | ||
// ``` | ||
// | ||
// This case is not (very?) useful: | ||
// | ||
// ```mdx | ||
// {a}<b/> | ||
// ``` | ||
// | ||
// …but it would be tougher than needed to disallow. | ||
// | ||
// To allow that, here we call the flow construct of | ||
// `micromark-extension-mdx-jsx`, and there we call this one. | ||
// | ||
// It would introduce a cyclical interdependency if we test JSX and | ||
// expressions here. | ||
// Because the JSX extension already uses parts of this monorepo, we | ||
// instead test it there. | ||
const lessThanValue = self.parser.constructs.flow[60]; | ||
const constructs = Array.isArray(lessThanValue) ? lessThanValue : /* c8 ignore next 3 -- always a list when normalized. */ | ||
lessThanValue ? [lessThanValue] : []; | ||
const jsxTag = constructs.find(function (d) { | ||
return d.name === 'mdxJsxFlowTag'; | ||
}); | ||
/* c8 ignore next 3 -- this is tested in `micromark-extension-mdx-jsx` */ | ||
if (code === 60 && jsxTag) { | ||
return effects.attempt(jsxTag, end, nok)(code); | ||
} | ||
return code === null || markdownLineEnding(code) ? ok(code) : nok(code); | ||
} | ||
@@ -203,4 +220,4 @@ } | ||
function tokenizeTextExpression(effects, ok) { | ||
const self = this | ||
return start | ||
const self = this; | ||
return start; | ||
@@ -219,18 +236,5 @@ /** | ||
function start(code) { | ||
return factoryMdxExpression.call( | ||
self, | ||
effects, | ||
ok, | ||
'mdxTextExpression', | ||
'mdxTextExpressionMarker', | ||
'mdxTextExpressionChunk', | ||
acorn, | ||
acornOptions, | ||
addResult, | ||
spread, | ||
allowEmpty, | ||
true | ||
)(code) | ||
return factoryMdxExpression.call(self, effects, ok, 'mdxTextExpression', 'mdxTextExpressionMarker', 'mdxTextExpressionChunk', acorn, acornOptions, addResult, spread, allowEmpty, true)(code); | ||
} | ||
} | ||
} | ||
} |
{ | ||
"name": "micromark-extension-mdx-expression", | ||
"version": "2.0.0", | ||
"version": "3.0.0", | ||
"description": "micromark extension to support MDX or MDX JS expressions", | ||
@@ -66,3 +66,8 @@ "license": "MIT", | ||
}, | ||
"xo": false | ||
"xo": { | ||
"prettier": true, | ||
"rules": { | ||
"unicorn/no-this-assignment": "off" | ||
} | ||
} | ||
} |
@@ -167,3 +167,3 @@ # micromark-extension-mdx-expression | ||
* `acornOptions` ([`AcornOptions`][acorn-options], default: | ||
`{ecmaVersion: 2020, locations: true, sourceType: 'module'}`) | ||
`{ecmaVersion: 2024, locations: true, sourceType: 'module'}`) | ||
— configuration for acorn; all fields except `locations` can be set | ||
@@ -170,0 +170,0 @@ * `addResult` (`boolean`, default: `false`) |
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
33867
609