micromark-factory-mdx-expression
Advanced tools
Comparing version 1.0.4 to 1.0.5
@@ -16,8 +16,20 @@ /** | ||
*/ | ||
export function factoryMdxExpression(effects: Effects, ok: State, type: string, markerType: string, chunkType: string, acorn?: import("micromark-util-events-to-acorn").Acorn | undefined, acornOptions?: import("acorn").Options | undefined, addResult?: boolean | undefined, spread?: boolean | undefined, allowEmpty?: boolean | undefined, allowLazy?: boolean | undefined): State; | ||
export type Point = import('micromark-util-types').Point; | ||
export type TokenizeContext = import('micromark-util-types').TokenizeContext; | ||
export type Effects = import('micromark-util-types').Effects; | ||
export type State = import('micromark-util-types').State; | ||
export type Acorn = import('micromark-util-events-to-acorn').Acorn; | ||
export type AcornOptions = import('micromark-util-events-to-acorn').AcornOptions; | ||
export function factoryMdxExpression( | ||
effects: Effects, | ||
ok: State, | ||
type: string, | ||
markerType: string, | ||
chunkType: string, | ||
acorn?: import('micromark-util-events-to-acorn').Acorn | undefined, | ||
acornOptions?: import('acorn').Options | undefined, | ||
addResult?: boolean | undefined, | ||
spread?: boolean | undefined, | ||
allowEmpty?: boolean | undefined, | ||
allowLazy?: boolean | undefined | ||
): State | ||
export type Point = import('micromark-util-types').Point | ||
export type TokenizeContext = import('micromark-util-types').TokenizeContext | ||
export type Effects = import('micromark-util-types').Effects | ||
export type State = import('micromark-util-types').State | ||
export type Acorn = import('micromark-util-events-to-acorn').Acorn | ||
export type AcornOptions = import('micromark-util-events-to-acorn').AcornOptions |
@@ -177,10 +177,18 @@ /** | ||
assert(head, 'expected body') | ||
assert(head.type === 'ExpressionStatement', 'expected expression') | ||
assert( | ||
head.expression.type === 'ObjectExpression', | ||
'expected object expression' | ||
) | ||
if (head.expression.properties[1]) { | ||
// Can occur in some complex attributes. | ||
/* c8 ignore next 11 */ | ||
if ( | ||
head.type !== 'ExpressionStatement' || | ||
head.expression.type !== 'ObjectExpression' | ||
) { | ||
throw new VFileMessage( | ||
'Unexpected `' + | ||
head.type + | ||
'` in code: expected an object spread (`{...spread}`)', | ||
positionFromEstree(head).start, | ||
'micromark-extension-mdx-expression:non-spread' | ||
) | ||
} else if (head.expression.properties[1]) { | ||
throw new VFileMessage( | ||
'Unexpected extra content in spread: only a single spread is supported', | ||
@@ -187,0 +195,0 @@ positionFromEstree(head.expression.properties[1]).start, |
@@ -16,8 +16,20 @@ /** | ||
*/ | ||
export function factoryMdxExpression(effects: Effects, ok: State, type: string, markerType: string, chunkType: string, acorn?: import("micromark-util-events-to-acorn").Acorn | undefined, acornOptions?: import("acorn").Options | undefined, addResult?: boolean | undefined, spread?: boolean | undefined, allowEmpty?: boolean | undefined, allowLazy?: boolean | undefined): State; | ||
export type Point = import('micromark-util-types').Point; | ||
export type TokenizeContext = import('micromark-util-types').TokenizeContext; | ||
export type Effects = import('micromark-util-types').Effects; | ||
export type State = import('micromark-util-types').State; | ||
export type Acorn = import('micromark-util-events-to-acorn').Acorn; | ||
export type AcornOptions = import('micromark-util-events-to-acorn').AcornOptions; | ||
export function factoryMdxExpression( | ||
effects: Effects, | ||
ok: State, | ||
type: string, | ||
markerType: string, | ||
chunkType: string, | ||
acorn?: import('micromark-util-events-to-acorn').Acorn | undefined, | ||
acornOptions?: import('acorn').Options | undefined, | ||
addResult?: boolean | undefined, | ||
spread?: boolean | undefined, | ||
allowEmpty?: boolean | undefined, | ||
allowLazy?: boolean | undefined | ||
): State | ||
export type Point = import('micromark-util-types').Point | ||
export type TokenizeContext = import('micromark-util-types').TokenizeContext | ||
export type Effects = import('micromark-util-types').Effects | ||
export type State = import('micromark-util-types').State | ||
export type Acorn = import('micromark-util-events-to-acorn').Acorn | ||
export type AcornOptions = import('micromark-util-events-to-acorn').AcornOptions |
220
index.js
@@ -9,7 +9,7 @@ /** | ||
*/ | ||
import { markdownLineEnding } from 'micromark-util-character'; | ||
import { factorySpace } from 'micromark-factory-space'; | ||
import { positionFromEstree } from 'unist-util-position-from-estree'; | ||
import { VFileMessage } from 'vfile-message'; | ||
import { eventsToAcorn } from 'micromark-util-events-to-acorn'; | ||
import {markdownLineEnding} from 'micromark-util-character' | ||
import {factorySpace} from 'micromark-factory-space' | ||
import {positionFromEstree} from 'unist-util-position-from-estree' | ||
import {VFileMessage} from 'vfile-message' | ||
import {eventsToAcorn} from 'micromark-util-events-to-acorn' | ||
/** | ||
@@ -32,94 +32,122 @@ * @this {TokenizeContext} | ||
export function factoryMdxExpression(effects, ok, type, markerType, chunkType, acorn, acornOptions, addResult, spread, allowEmpty, allowLazy) { | ||
const self = this; | ||
const eventStart = this.events.length + 3; // Add main and marker token | ||
export function factoryMdxExpression( | ||
effects, | ||
ok, | ||
type, | ||
markerType, | ||
chunkType, | ||
acorn, | ||
acornOptions, | ||
addResult, | ||
spread, | ||
allowEmpty, | ||
allowLazy | ||
) { | ||
const self = this | ||
const eventStart = this.events.length + 3 // Add main and marker token | ||
const tail = this.events[this.events.length - 1]; | ||
const initialPrefix = tail && tail[1].type === "linePrefix" ? tail[2].sliceSerialize(tail[1], true).length : 0; | ||
let balance = 1; | ||
const tail = this.events[this.events.length - 1] | ||
const initialPrefix = | ||
tail && tail[1].type === 'linePrefix' | ||
? tail[2].sliceSerialize(tail[1], true).length | ||
: 0 | ||
let balance = 1 | ||
/** @type {Point} */ | ||
let startPosition; | ||
let startPosition | ||
/** @type {Error} */ | ||
let lastCrash; | ||
return start; | ||
let lastCrash | ||
return start | ||
/** @type {State} */ | ||
function start(code) { | ||
effects.enter(type); | ||
effects.enter(markerType); | ||
effects.consume(code); | ||
effects.exit(markerType); | ||
startPosition = self.now(); | ||
return atBreak; | ||
effects.enter(type) | ||
effects.enter(markerType) | ||
effects.consume(code) | ||
effects.exit(markerType) | ||
startPosition = self.now() | ||
return atBreak | ||
} | ||
/** @type {State} */ | ||
function atBreak(code) { | ||
if (code === null) { | ||
throw lastCrash || new VFileMessage('Unexpected end of file in expression, expected a corresponding closing brace for `{`', self.now(), 'micromark-extension-mdx-expression:unexpected-eof'); | ||
throw ( | ||
lastCrash || | ||
new VFileMessage( | ||
'Unexpected end of file in expression, expected a corresponding closing brace for `{`', | ||
self.now(), | ||
'micromark-extension-mdx-expression:unexpected-eof' | ||
) | ||
) | ||
} | ||
if (code === 125) { | ||
return atClosingBrace(code); | ||
return atClosingBrace(code) | ||
} | ||
if (markdownLineEnding(code)) { | ||
effects.enter("lineEnding"); | ||
effects.consume(code); | ||
effects.exit("lineEnding"); // Return atBreak | ||
effects.enter('lineEnding') | ||
effects.consume(code) | ||
effects.exit('lineEnding') // Return atBreak | ||
return initialPrefix ? factorySpace(effects, atBreak, "linePrefix", initialPrefix + 1) : atBreak; | ||
return initialPrefix | ||
? factorySpace(effects, atBreak, 'linePrefix', initialPrefix + 1) | ||
: atBreak | ||
} | ||
const now = self.now(); | ||
const now = self.now() | ||
if (now.line !== startPosition.line && !allowLazy && self.parser.lazy[now.line]) { | ||
throw new VFileMessage('Unexpected end of file in expression, expected a corresponding closing brace for `{`', self.now(), 'micromark-extension-mdx-expression:unexpected-eof'); | ||
if ( | ||
now.line !== startPosition.line && | ||
!allowLazy && | ||
self.parser.lazy[now.line] | ||
) { | ||
throw new VFileMessage( | ||
'Unexpected end of file in expression, expected a corresponding closing brace for `{`', | ||
self.now(), | ||
'micromark-extension-mdx-expression:unexpected-eof' | ||
) | ||
} | ||
effects.enter(chunkType); | ||
return inside(code); | ||
effects.enter(chunkType) | ||
return inside(code) | ||
} | ||
/** @type {State} */ | ||
function inside(code) { | ||
if (code === null || code === 125 || markdownLineEnding(code)) { | ||
effects.exit(chunkType); | ||
return atBreak(code); | ||
effects.exit(chunkType) | ||
return atBreak(code) | ||
} | ||
if (code === 123 && !acorn) { | ||
effects.consume(code); | ||
balance++; | ||
return inside; | ||
effects.consume(code) | ||
balance++ | ||
return inside | ||
} | ||
effects.consume(code); | ||
return inside; | ||
effects.consume(code) | ||
return inside | ||
} | ||
/** @type {State} */ | ||
function atClosingBrace(code) { | ||
balance--; // Agnostic mode: count balanced braces. | ||
balance-- // Agnostic mode: count balanced braces. | ||
if (!acorn) { | ||
if (balance) { | ||
effects.enter(chunkType); | ||
effects.consume(code); | ||
return inside; | ||
effects.enter(chunkType) | ||
effects.consume(code) | ||
return inside | ||
} | ||
effects.enter(markerType); | ||
effects.consume(code); | ||
effects.exit(markerType); | ||
effects.exit(type); | ||
return ok; | ||
effects.enter(markerType) | ||
effects.consume(code) | ||
effects.exit(markerType) | ||
effects.exit(type) | ||
return ok | ||
} // Gnostic mode: parse w/ acorn. | ||
const result = eventsToAcorn(self.events.slice(eventStart), { | ||
@@ -133,13 +161,40 @@ acorn, | ||
suffix: spread ? '})' : '' | ||
}); | ||
const estree = result.estree; // Get the spread value. | ||
}) | ||
const estree = result.estree // Get the spread value. | ||
if (spread && estree) { | ||
// Should always be the case as we wrap in `d={}` | ||
const head = estree.body[0]; | ||
const head = estree.body[0] | ||
if (head.expression.properties[1]) { | ||
throw new VFileMessage('Unexpected extra content in spread: only a single spread is supported', positionFromEstree(head.expression.properties[1]).start, 'micromark-extension-mdx-expression:spread-extra'); | ||
} else if (head.expression.properties[0] && head.expression.properties[0].type !== 'SpreadElement') { | ||
throw new VFileMessage('Unexpected `' + head.expression.properties[0].type + '` in code: only spread elements are supported', positionFromEstree(head.expression.properties[0]).start, 'micromark-extension-mdx-expression:non-spread'); | ||
// Can occur in some complex attributes. | ||
/* c8 ignore next 11 */ | ||
if ( | ||
head.type !== 'ExpressionStatement' || | ||
head.expression.type !== 'ObjectExpression' | ||
) { | ||
throw new VFileMessage( | ||
'Unexpected `' + | ||
head.type + | ||
'` in code: expected an object spread (`{...spread}`)', | ||
positionFromEstree(head).start, | ||
'micromark-extension-mdx-expression:non-spread' | ||
) | ||
} else if (head.expression.properties[1]) { | ||
throw new VFileMessage( | ||
'Unexpected extra content in spread: only a single spread is supported', | ||
positionFromEstree(head.expression.properties[1]).start, | ||
'micromark-extension-mdx-expression:spread-extra' | ||
) | ||
} else if ( | ||
head.expression.properties[0] && | ||
head.expression.properties[0].type !== 'SpreadElement' | ||
) { | ||
throw new VFileMessage( | ||
'Unexpected `' + | ||
head.expression.properties[0].type + | ||
'` in code: only spread elements are supported', | ||
positionFromEstree(head.expression.properties[0]).start, | ||
'micromark-extension-mdx-expression:non-spread' | ||
) | ||
} | ||
@@ -149,28 +204,37 @@ } | ||
if (result.error) { | ||
lastCrash = new VFileMessage('Could not parse expression with acorn: ' + result.error.message, { | ||
// @ts-expect-error: fine. | ||
line: result.error.loc.line, | ||
// @ts-expect-error: fine. | ||
column: result.error.loc.column + 1, | ||
// @ts-expect-error: fine. | ||
offset: result.error.pos | ||
}, 'micromark-extension-mdx-expression:acorn'); | ||
lastCrash = new VFileMessage( | ||
'Could not parse expression with acorn: ' + result.error.message, | ||
{ | ||
// @ts-expect-error: fine. | ||
line: result.error.loc.line, | ||
// @ts-expect-error: fine. | ||
column: result.error.loc.column + 1, | ||
// @ts-expect-error: fine. | ||
offset: result.error.pos | ||
}, | ||
'micromark-extension-mdx-expression:acorn' | ||
) | ||
if (code !== null && result.swallow) { | ||
effects.enter(chunkType); | ||
effects.consume(code); | ||
return inside; | ||
effects.enter(chunkType) | ||
effects.consume(code) | ||
return inside | ||
} | ||
throw lastCrash; | ||
throw lastCrash | ||
} | ||
effects.enter(markerType); | ||
effects.consume(code); | ||
effects.exit(markerType); | ||
Object.assign(effects.exit(type), addResult ? { | ||
estree | ||
} : undefined); | ||
return ok; | ||
effects.enter(markerType) | ||
effects.consume(code) | ||
effects.exit(markerType) | ||
Object.assign( | ||
effects.exit(type), | ||
addResult | ||
? { | ||
estree | ||
} | ||
: undefined | ||
) | ||
return ok | ||
} | ||
} | ||
} |
{ | ||
"name": "micromark-factory-mdx-expression", | ||
"version": "1.0.4", | ||
"version": "1.0.5", | ||
"description": "micromark factory to parse MDX expressions (found in JSX attributes, flow, text)", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
@@ -74,3 +74,3 @@ # micromark-factory-mdx-expression | ||
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. | ||
@@ -77,0 +77,0 @@ Without this condition, production code is loaded. |
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
21964
495