112 lines
2.9 KiB
JavaScript
112 lines
2.9 KiB
JavaScript
/**
|
|
* @typedef {import('mdast-util-from-markdown').CompileContext} CompileContext
|
|
* @typedef {import('mdast-util-from-markdown').Extension} FromMarkdownExtension
|
|
* @typedef {import('mdast-util-from-markdown').Handle} FromMarkdownHandle
|
|
*
|
|
* @typedef {import('mdast-util-to-markdown').Handle} ToMarkdownHandle
|
|
* @typedef {import('mdast-util-to-markdown').Options} ToMarkdownExtension
|
|
*
|
|
* @typedef {import('../index.js').MdxFlowExpression} MdxFlowExpression
|
|
* @typedef {import('../index.js').MdxTextExpression} MdxTextExpression
|
|
*/
|
|
|
|
import {ok as assert} from 'devlop'
|
|
|
|
/**
|
|
* Create an extension for `mdast-util-from-markdown` to enable MDX expressions
|
|
* in markdown.
|
|
*
|
|
* When using the micromark syntax extension with `addResult`, nodes will have
|
|
* a `data.estree` field set to an ESTree `Program` node.
|
|
*
|
|
* @returns {FromMarkdownExtension}
|
|
* Extension for `mdast-util-from-markdown` to enable MDX expressions.
|
|
*/
|
|
export function mdxExpressionFromMarkdown() {
|
|
return {
|
|
enter: {
|
|
mdxFlowExpression: enterMdxFlowExpression,
|
|
mdxTextExpression: enterMdxTextExpression
|
|
},
|
|
exit: {
|
|
mdxFlowExpression: exitMdxExpression,
|
|
mdxFlowExpressionChunk: exitMdxExpressionData,
|
|
mdxTextExpression: exitMdxExpression,
|
|
mdxTextExpressionChunk: exitMdxExpressionData
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create an extension for `mdast-util-to-markdown` to enable MDX expressions
|
|
* in markdown.
|
|
*
|
|
* @returns {ToMarkdownExtension}
|
|
* Extension for `mdast-util-to-markdown` to enable MDX expressions.
|
|
*/
|
|
export function mdxExpressionToMarkdown() {
|
|
return {
|
|
handlers: {
|
|
mdxFlowExpression: handleMdxExpression,
|
|
mdxTextExpression: handleMdxExpression
|
|
},
|
|
unsafe: [
|
|
{character: '{', inConstruct: ['phrasing']},
|
|
{atBreak: true, character: '{'}
|
|
]
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @this {CompileContext}
|
|
* @type {FromMarkdownHandle}
|
|
*/
|
|
function enterMdxFlowExpression(token) {
|
|
this.enter({type: 'mdxFlowExpression', value: ''}, token)
|
|
this.buffer()
|
|
}
|
|
|
|
/**
|
|
* @this {CompileContext}
|
|
* @type {FromMarkdownHandle}
|
|
*/
|
|
function enterMdxTextExpression(token) {
|
|
this.enter({type: 'mdxTextExpression', value: ''}, token)
|
|
this.buffer()
|
|
}
|
|
|
|
/**
|
|
* @this {CompileContext}
|
|
* @type {FromMarkdownHandle}
|
|
*/
|
|
function exitMdxExpression(token) {
|
|
const value = this.resume()
|
|
const estree = token.estree
|
|
const node = this.stack[this.stack.length - 1]
|
|
assert(node.type === 'mdxFlowExpression' || node.type === 'mdxTextExpression')
|
|
this.exit(token)
|
|
node.value = value
|
|
|
|
if (estree) {
|
|
node.data = {estree}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @this {CompileContext}
|
|
* @type {FromMarkdownHandle}
|
|
*/
|
|
function exitMdxExpressionData(token) {
|
|
this.config.enter.data.call(this, token)
|
|
this.config.exit.data.call(this, token)
|
|
}
|
|
|
|
/**
|
|
* @type {ToMarkdownHandle}
|
|
* @param {MdxFlowExpression | MdxTextExpression} node
|
|
*/
|
|
function handleMdxExpression(node) {
|
|
const value = node.value || ''
|
|
return '{' + value + '}'
|
|
}
|