@mdx-js/mdx
Advanced tools
Comparing version 2.0.0-next.8 to 2.0.0-next.9
127
index.js
const unified = require('unified') | ||
const toMDAST = require('remark-parse') | ||
const remarkParse = require('remark-parse') | ||
const remarkMdx = require('remark-mdx') | ||
const remarkMdxJs = require('remark-mdxjs') | ||
const footnotes = require('remark-footnotes') | ||
const squeeze = require('remark-squeeze-paragraphs') | ||
const visit = require('unist-util-visit') | ||
const raw = require('hast-util-raw') | ||
const minifyWhitespace = require('rehype-minify-whitespace') | ||
const mdxAstToMdxHast = require('./mdx-ast-to-mdx-hast') | ||
const mdxHastToJsx = require('./mdx-hast-to-jsx') | ||
const DEFAULT_OPTIONS = { | ||
remarkPlugins: [], | ||
rehypePlugins: [], | ||
compilers: [] | ||
} | ||
const pragma = `/* @jsxRuntime classic */ | ||
/* @jsx mdx */ | ||
/* @jsxFrag mdx.Fragment */` | ||
function createMdxAstCompiler(options) { | ||
const plugins = options.remarkPlugins | ||
const fn = unified() | ||
.use(toMDAST, options) | ||
.use(remarkMdx, options) | ||
.use(remarkMdxJs, options) | ||
.use(footnotes, options) | ||
.use(squeeze, options) | ||
plugins.forEach(plugin => { | ||
// Handle [plugin, pluginOptions] syntax | ||
if (Array.isArray(plugin) && plugin.length > 1) { | ||
fn.use(plugin[0], plugin[1]) | ||
} else { | ||
fn.use(plugin) | ||
} | ||
}) | ||
fn.use(mdxAstToMdxHast, options) | ||
return fn | ||
function createMdxAstCompiler(options = {}) { | ||
return unified() | ||
.use(remarkParse) | ||
.use(remarkMdx) | ||
.use(squeeze) | ||
.use(options.remarkPlugins) | ||
.use(mdxAstToMdxHast) | ||
} | ||
function applyHastPluginsAndCompilers(compiler, options) { | ||
const plugins = options.rehypePlugins | ||
const compilers = options.compilers | ||
// Convert raw nodes into HAST | ||
compiler.use(() => ast => { | ||
visit(ast, 'raw', node => { | ||
const {children, tagName, properties} = raw(node) | ||
node.type = 'element' | ||
node.children = children | ||
node.tagName = tagName | ||
node.properties = properties | ||
}) | ||
}) | ||
plugins.forEach(plugin => { | ||
// Handle [plugin, pluginOptions] syntax | ||
if (Array.isArray(plugin) && plugin.length > 1) { | ||
compiler.use(plugin[0], plugin[1]) | ||
} else { | ||
compiler.use(plugin) | ||
} | ||
}) | ||
compiler.use(mdxHastToJsx, options) | ||
for (const compilerPlugin of compilers) { | ||
compiler.use(compilerPlugin, options) | ||
} | ||
return compiler | ||
} | ||
function createCompiler(options = {}) { | ||
const opts = Object.assign({}, DEFAULT_OPTIONS, options) | ||
const compiler = createMdxAstCompiler(opts) | ||
const compilerWithPlugins = applyHastPluginsAndCompilers(compiler, opts) | ||
return compilerWithPlugins | ||
return createMdxAstCompiler(options) | ||
.use(options.rehypePlugins) | ||
.use(minifyWhitespace, {newlines: true}) | ||
.use(mdxHastToJsx, options) | ||
} | ||
function sync(mdx, options = {}) { | ||
const compiler = createCompiler(options) | ||
function createConfig(mdx, options) { | ||
const config = {contents: mdx} | ||
const fileOpts = {contents: mdx} | ||
if (options.filepath) { | ||
fileOpts.path = options.filepath | ||
config.path = options.filepath | ||
} | ||
const {contents} = compiler.processSync(fileOpts) | ||
return config | ||
} | ||
return `/* @jsx mdx */ | ||
${contents}` | ||
function sync(mdx, options = {}) { | ||
const file = createCompiler(options).processSync(createConfig(mdx, options)) | ||
return pragma + '\n' + String(file) | ||
} | ||
async function compile(mdx, options = {}) { | ||
const compiler = createCompiler(options) | ||
const fileOpts = {contents: mdx} | ||
if (options.filepath) { | ||
fileOpts.path = options.filepath | ||
} | ||
const {contents} = await compiler.process(fileOpts) | ||
return `/* @jsx mdx */ | ||
${contents}` | ||
const file = await createCompiler(options).process(createConfig(mdx, options)) | ||
return pragma + '\n' + String(file) | ||
} | ||
module.exports = compile | ||
compile.default = compile | ||
compile.sync = sync | ||
module.exports = compile | ||
exports = compile | ||
exports.sync = sync | ||
exports.createMdxAstCompiler = createMdxAstCompiler | ||
exports.createCompiler = createCompiler | ||
exports.default = compile | ||
compile.createMdxAstCompiler = createMdxAstCompiler | ||
compile.createCompiler = createCompiler |
@@ -1,3 +0,2 @@ | ||
const toHAST = require('mdast-util-to-hast') | ||
const all = require('mdast-util-to-hast/lib/all') | ||
const toHast = require('mdast-util-to-hast') | ||
const detab = require('detab') | ||
@@ -7,95 +6,61 @@ const u = require('unist-builder') | ||
function mdxAstToMdxHast() { | ||
return (tree, _file) => { | ||
const handlers = { | ||
// `inlineCode` gets passed as `code` by the HAST transform. | ||
// This makes sure it ends up being `inlineCode` | ||
inlineCode(h, node) { | ||
return Object.assign({}, node, { | ||
type: 'element', | ||
tagName: 'inlineCode', | ||
properties: {}, | ||
children: [ | ||
{ | ||
type: 'text', | ||
value: node.value | ||
} | ||
] | ||
}) | ||
}, | ||
code(h, node) { | ||
const value = node.value ? detab(node.value + '\n') : '' | ||
const lang = node.lang | ||
const props = {} | ||
return tree => { | ||
return toHast(tree, { | ||
passThrough: [ | ||
'mdxFlowExpression', | ||
'mdxJsxFlowElement', | ||
'mdxJsxTextElement', | ||
'mdxTextExpression', | ||
'mdxjsEsm' | ||
], | ||
handlers: { | ||
// Use a custom `inlineCode` element for inline code. | ||
inlineCode(h, node) { | ||
return h(node, 'inlineCode', [{type: 'text', value: node.value}]) | ||
}, | ||
// Add a custom `metastring` attribute to `code` elements, | ||
// and support it also as a key/value attribute setter. | ||
code(h, node) { | ||
const value = node.value ? detab(node.value + '\n') : '' | ||
const lang = node.lang | ||
const props = {} | ||
if (lang) { | ||
props.className = ['language-' + lang] | ||
} | ||
if (lang) { | ||
props.className = ['language-' + lang] | ||
} | ||
// MDAST sets `node.meta` to `null` instead of `undefined` if | ||
// not present, which React doesn't like. | ||
props.metastring = node.meta || undefined | ||
props.metastring = node.meta | ||
const meta = | ||
node.meta && | ||
node.meta.split(' ').reduce((acc, cur) => { | ||
if (cur.split('=').length > 1) { | ||
const t = cur.split('=') | ||
acc[t[0]] = t[1] | ||
// To do: this handling seems not what users expect: | ||
// <https://github.com/mdx-js/mdx/issues/702>. | ||
const meta = | ||
node.meta && | ||
node.meta.split(' ').reduce((acc, cur) => { | ||
if (cur.split('=').length > 1) { | ||
const t = cur.split('=') | ||
acc[t[0]] = t[1] | ||
return acc | ||
} | ||
acc[cur] = true | ||
return acc | ||
} | ||
}, {}) | ||
acc[cur] = true | ||
return acc | ||
}, {}) | ||
if (meta) { | ||
Object.keys(meta).forEach(key => { | ||
const isClassKey = key === 'class' || key === 'className' | ||
if (props.className && isClassKey) { | ||
props.className.push(meta[key]) | ||
} else { | ||
props[key] = meta[key] | ||
} | ||
}) | ||
} | ||
if (meta) { | ||
Object.keys(meta).forEach(key => { | ||
const isClassKey = key === 'class' || key === 'className' | ||
if (props.className && isClassKey) { | ||
props.className.push(meta[key]) | ||
} else { | ||
props[key] = meta[key] | ||
} | ||
}) | ||
return h(node.position, 'pre', [ | ||
h(node, 'code', props, [u('text', value)]) | ||
]) | ||
} | ||
return h(node.position, 'pre', [ | ||
h(node, 'code', props, [u('text', value)]) | ||
]) | ||
}, | ||
// To do: rename to `mdxJsImport` | ||
import(h, node) { | ||
return Object.assign({}, node, { | ||
type: 'import' | ||
}) | ||
}, | ||
// To do: rename to `mdxJsExport` | ||
export(h, node) { | ||
return Object.assign({}, node, { | ||
type: 'export' | ||
}) | ||
}, | ||
mdxBlockElement(h, node) { | ||
return Object.assign({}, node, {children: all(h, node)}) | ||
}, | ||
mdxSpanElement(h, node) { | ||
return Object.assign({}, node, {children: all(h, node)}) | ||
}, | ||
mdxBlockExpression(h, node) { | ||
return Object.assign({}, node, { | ||
type: 'mdxBlockExpression' | ||
}) | ||
}, | ||
mdxSpanExpression(h, node) { | ||
return Object.assign({}, node, { | ||
type: 'mdxSpanExpression' | ||
}) | ||
} | ||
} | ||
const hast = toHAST(tree, { | ||
handlers | ||
}) | ||
return hast | ||
} | ||
@@ -102,0 +67,0 @@ } |
@@ -1,51 +0,7 @@ | ||
const {transformSync} = require('@babel/core') | ||
const uniq = require('lodash.uniq') | ||
const {serializeTags} = require('remark-mdx/lib/serialize/mdx-element') | ||
const serializeMdxExpression = require('remark-mdx/lib/serialize/mdx-expression') | ||
const toH = require('hast-to-hyperscript') | ||
const {toTemplateLiteral} = require('@mdx-js/util') | ||
const BabelPluginApplyMdxProp = require('babel-plugin-apply-mdx-type-prop') | ||
const BabelPluginExtractImportNames = require('babel-plugin-extract-import-names') | ||
const BabelPluginExtractExportNames = require('babel-plugin-extract-export-names') | ||
const toEstree = require('hast-util-to-estree') | ||
const walk = require('estree-walker').walk | ||
const periscopic = require('periscopic') | ||
const estreeToJs = require('./estree-to-js') | ||
function toJSX(node, parentNode = {}, options = {}) { | ||
if (node.type === 'root') { | ||
return serializeRoot(node, options) | ||
} | ||
if (node.type === 'element') { | ||
return serializeElement(node, options, parentNode) | ||
} | ||
// Wraps text nodes inside template string, so that we don't run into escaping issues. | ||
if (node.type === 'text') { | ||
return serializeText(node, options, parentNode) | ||
} | ||
if (node.type === 'mdxBlockExpression' || node.type === 'mdxSpanExpression') { | ||
return serializeMdxExpression(node) | ||
} | ||
// To do: pass `parentName` in? | ||
if (node.type === 'mdxBlockElement' || node.type === 'mdxSpanElement') { | ||
return serializeComponent(node, options, parentNode) | ||
} | ||
if (node.type === 'import' || node.type === 'export') { | ||
return serializeEsSyntax(node) | ||
} | ||
} | ||
function compile(options = {}) { | ||
this.Compiler = function (tree) { | ||
return toJSX(tree, {}, options) | ||
} | ||
} | ||
module.exports = compile | ||
exports = compile | ||
exports.toJSX = toJSX | ||
exports.default = compile | ||
function serializeRoot(node, options) { | ||
function serializeEstree(estree, options) { | ||
const { | ||
@@ -57,22 +13,49 @@ // Default options | ||
const groups = {import: [], export: [], rest: []} | ||
let layout | ||
let children = [] | ||
let mdxLayoutDefault | ||
for (const child of node.children) { | ||
let kind = 'rest' | ||
if (child.type === 'import' || child.type === 'export') { | ||
kind = child.type | ||
// Find the `export default`, the JSX expression, and leave the rest | ||
// (import/exports) as they are. | ||
estree.body = estree.body.filter(child => { | ||
// ```js | ||
// export default a = 1 | ||
// ``` | ||
if (child.type === 'ExportDefaultDeclaration') { | ||
layout = child.declaration | ||
return false | ||
} | ||
groups[kind].push(child) | ||
} | ||
// ```js | ||
// export {default} from "a" | ||
// export {default as a} from "b" | ||
// export {default as a, b} from "c" | ||
// export {a as default} from "b" | ||
// export {a as default, b} from "c" | ||
// ``` | ||
if (child.type === 'ExportNamedDeclaration' && child.source) { | ||
// Remove `default` or `as default`, but not `default as`, specifier. | ||
child.specifiers = child.specifiers.filter(specifier => { | ||
if (specifier.exported.name === 'default') { | ||
mdxLayoutDefault = {local: specifier.local, source: child.source} | ||
return false | ||
} | ||
let layout | ||
return true | ||
}) | ||
// Find a default export, assumes there’s zero or one. | ||
groups.export = groups.export.filter(child => { | ||
if (child.default) { | ||
layout = child.value | ||
.replace(/^export\s+default\s+/, '') | ||
.replace(/;\s*$/, '') | ||
// Keep the export if there are other specifiers, drop it if there was | ||
// just a default. | ||
return child.specifiers.length > 0 | ||
} | ||
if ( | ||
child.type === 'ExpressionStatement' && | ||
(child.expression.type === 'JSXFragment' || | ||
child.expression.type === 'JSXElement') | ||
) { | ||
children = | ||
child.expression.type === 'JSXFragment' | ||
? child.expression.children | ||
: [child.expression] | ||
return false | ||
@@ -84,180 +67,331 @@ } | ||
const importStatements = groups.import | ||
.map(childNode => toJSX(childNode, node)) | ||
.join('\n') | ||
// Find everything that’s defined in the top-level scope. | ||
// Do this here because `estree` currently only includes import/exports | ||
// and we don’t have to walk all the JSX to figure out the top scope. | ||
const inTopScope = [ | ||
'MDXLayout', | ||
'MDXContent', | ||
...periscopic.analyze(estree).scope.declarations.keys() | ||
] | ||
const exportStatements = groups.export | ||
.map(childNode => toJSX(childNode, node)) | ||
.join('\n') | ||
estree.body = [ | ||
...estree.body, | ||
...createMdxLayout(layout, mdxLayoutDefault), | ||
...createMdxContent(children) | ||
] | ||
const mdxLayout = `const MDXLayout = ${layout ? layout : '"wrapper"'}` | ||
// Add `mdxType`, `parentName` props to JSX elements. | ||
const magicShortcodes = [] | ||
const stack = [] | ||
const doc = groups.rest | ||
.map(childNode => toJSX(childNode, node, options)) | ||
.join('') | ||
.replace(/^\n+|\n+$/, '') | ||
walk(estree, { | ||
enter: function (node) { | ||
if ( | ||
node.type === 'JSXElement' && | ||
// To do: support members (`<x.y>`). | ||
node.openingElement.name.type === 'JSXIdentifier' | ||
) { | ||
const name = node.openingElement.name.name | ||
const fn = `function MDXContent({ components, ...props }) { | ||
return ( | ||
<MDXLayout {...props} components={components}> | ||
${doc} | ||
</MDXLayout> | ||
) | ||
}; | ||
MDXContent.isMDXComponent = true` | ||
if (stack.length > 1) { | ||
const parentName = stack[stack.length - 1] | ||
// Check JSX nodes against imports | ||
const babelPluginExtractImportNamesInstance = new BabelPluginExtractImportNames() | ||
const babelPluginExtractExportNamesInstance = new BabelPluginExtractExportNames() | ||
const importsAndExports = [importStatements, exportStatements].join('\n') | ||
transformSync(importsAndExports, { | ||
configFile: false, | ||
babelrc: false, | ||
plugins: [ | ||
require('@babel/plugin-syntax-jsx'), | ||
require('@babel/plugin-syntax-object-rest-spread'), | ||
babelPluginExtractImportNamesInstance.plugin, | ||
babelPluginExtractExportNamesInstance.plugin | ||
] | ||
}) | ||
const importNames = babelPluginExtractImportNamesInstance.state.names | ||
const exportNames = babelPluginExtractExportNamesInstance.state.names | ||
node.openingElement.attributes.push({ | ||
type: 'JSXAttribute', | ||
name: {type: 'JSXIdentifier', name: 'parentName'}, | ||
value: { | ||
type: 'Literal', | ||
value: parentName, | ||
raw: JSON.stringify(parentName) | ||
} | ||
}) | ||
} | ||
const babelPluginApplyMdxPropInstance = new BabelPluginApplyMdxProp() | ||
const babelPluginApplyMdxPropToExportsInstance = new BabelPluginApplyMdxProp() | ||
const head = name.charAt(0) | ||
const fnPostMdxTypeProp = transformSync(fn, { | ||
configFile: false, | ||
babelrc: false, | ||
plugins: [ | ||
require('@babel/plugin-syntax-jsx'), | ||
require('@babel/plugin-syntax-object-rest-spread'), | ||
babelPluginApplyMdxPropInstance.plugin | ||
] | ||
}).code | ||
// A component. | ||
if (head === head.toUpperCase() && name !== 'MDXLayout') { | ||
node.openingElement.attributes.push({ | ||
type: 'JSXAttribute', | ||
name: {type: 'JSXIdentifier', name: 'mdxType'}, | ||
value: {type: 'Literal', value: name, raw: JSON.stringify(name)} | ||
}) | ||
const exportStatementsPostMdxTypeProps = transformSync(exportStatements, { | ||
configFile: false, | ||
babelrc: false, | ||
plugins: [ | ||
require('@babel/plugin-syntax-jsx'), | ||
require('@babel/plugin-syntax-object-rest-spread'), | ||
babelPluginApplyMdxPropToExportsInstance.plugin | ||
] | ||
}).code | ||
if (!inTopScope.includes(name) && !magicShortcodes.includes(name)) { | ||
magicShortcodes.push(name) | ||
} | ||
} | ||
const allJsxNames = [ | ||
...babelPluginApplyMdxPropInstance.state.names, | ||
...babelPluginApplyMdxPropToExportsInstance.state.names | ||
] | ||
const jsxNames = allJsxNames.filter(name => name !== 'MDXLayout') | ||
stack.push(name) | ||
} | ||
}, | ||
leave: function (node) { | ||
if ( | ||
node.type === 'JSXElement' && | ||
// To do: support members (`<x.y>`). | ||
node.openingElement.name.type === 'JSXIdentifier' | ||
) { | ||
stack.pop() | ||
} | ||
} | ||
}) | ||
const importExportNames = importNames.concat(exportNames) | ||
const fakedModulesForGlobalScope = | ||
`const makeShortcode = name => function MDXDefaultShortcode(props) { | ||
console.warn("Component " + name + " was not imported, exported, or provided by MDXProvider as global scope") | ||
return <div {...props}/> | ||
}; | ||
` + | ||
uniq(jsxNames) | ||
.filter(name => !importExportNames.includes(name)) | ||
.map(name => `const ${name} = makeShortcode("${name}");`) | ||
.join('\n') | ||
const exports = [] | ||
const moduleBase = `${importStatements} | ||
${exportStatementsPostMdxTypeProps} | ||
${fakedModulesForGlobalScope} | ||
${mdxLayout}` | ||
if (!skipExport) { | ||
let declaration = {type: 'Identifier', name: 'MDXContent'} | ||
if (skipExport) { | ||
return `${moduleBase} | ||
${fnPostMdxTypeProp}` | ||
} | ||
if (wrapExport) { | ||
declaration = { | ||
type: 'CallExpression', | ||
callee: {type: 'Identifier', name: wrapExport}, | ||
arguments: [declaration] | ||
} | ||
} | ||
if (wrapExport) { | ||
return `${moduleBase} | ||
${fnPostMdxTypeProp} | ||
export default ${wrapExport}(MDXContent)` | ||
exports.push({type: 'ExportDefaultDeclaration', declaration: declaration}) | ||
} | ||
return `${moduleBase} | ||
export default ${fnPostMdxTypeProp}` | ||
} | ||
estree.body = [ | ||
...createMakeShortcodeHelper( | ||
magicShortcodes, | ||
options.mdxFragment === false | ||
), | ||
...estree.body, | ||
...exports | ||
] | ||
function serializeElement(node, options, parentNode) { | ||
const parentName = parentNode.tagName | ||
const {type, props} = toH( | ||
fakeReactCreateElement, | ||
Object.assign({}, node, {children: []}), | ||
{prefix: false} | ||
) | ||
const content = serializeChildren(node, options) | ||
delete props.key | ||
const data = parentName ? {...props, parentName} : props | ||
const spread = | ||
Object.keys(data).length === 0 ? null : ' {...' + JSON.stringify(data) + '}' | ||
return ( | ||
'<' + | ||
type + | ||
(spread ? ' ' + spread : '') + | ||
(content ? '>' + content + '</' + type + '>' : '/>') | ||
) | ||
return estreeToJs(estree) | ||
} | ||
function serializeComponent(node, options) { | ||
let content = serializeChildren(node, options) | ||
const tags = serializeTags( | ||
Object.assign({}, node, {children: content ? ['!'] : []}) | ||
) | ||
if (node.type === 'mdxBlockElement' && content) { | ||
content = '\n' + content + '\n' | ||
function compile(options = {}) { | ||
function compiler(tree, file) { | ||
return serializeEstree(toEstree(tree), {filename: file.path, ...options}) | ||
} | ||
return tags.open + content + (tags.close || '') | ||
this.Compiler = compiler | ||
} | ||
function serializeText(node, options, parentNode) { | ||
const preserveNewlines = options.preserveNewlines | ||
// Don't wrap newlines unless specifically instructed to by the flag, | ||
// to avoid issues like React warnings caused by text nodes in tables. | ||
const shouldPreserveNewlines = preserveNewlines || parentNode.tagName === 'p' | ||
module.exports = compile | ||
compile.default = compile | ||
if (node.value === '\n' && !shouldPreserveNewlines) { | ||
return node.value | ||
} | ||
return toTemplateLiteral(node.value) | ||
function createMdxContent(children) { | ||
return [ | ||
{ | ||
type: 'FunctionDeclaration', | ||
id: {type: 'Identifier', name: 'MDXContent'}, | ||
expression: false, | ||
generator: false, | ||
async: false, | ||
params: [ | ||
{ | ||
type: 'ObjectPattern', | ||
properties: [ | ||
{ | ||
type: 'Property', | ||
method: false, | ||
shorthand: true, | ||
computed: false, | ||
key: {type: 'Identifier', name: 'components'}, | ||
kind: 'init', | ||
value: {type: 'Identifier', name: 'components'} | ||
}, | ||
{type: 'RestElement', argument: {type: 'Identifier', name: 'props'}} | ||
] | ||
} | ||
], | ||
body: { | ||
type: 'BlockStatement', | ||
body: [ | ||
{ | ||
type: 'ReturnStatement', | ||
argument: { | ||
type: 'JSXElement', | ||
openingElement: { | ||
type: 'JSXOpeningElement', | ||
attributes: [ | ||
{ | ||
type: 'JSXAttribute', | ||
name: {type: 'JSXIdentifier', name: 'components'}, | ||
value: { | ||
type: 'JSXExpressionContainer', | ||
expression: {type: 'Identifier', name: 'components'} | ||
} | ||
}, | ||
{ | ||
type: 'JSXSpreadAttribute', | ||
argument: {type: 'Identifier', name: 'props'} | ||
} | ||
], | ||
name: {type: 'JSXIdentifier', name: 'MDXLayout'}, | ||
selfClosing: false | ||
}, | ||
closingElement: { | ||
type: 'JSXClosingElement', | ||
name: {type: 'JSXIdentifier', name: 'MDXLayout'} | ||
}, | ||
children: children | ||
} | ||
} | ||
] | ||
} | ||
}, | ||
{ | ||
type: 'ExpressionStatement', | ||
expression: { | ||
type: 'AssignmentExpression', | ||
operator: '=', | ||
left: { | ||
type: 'MemberExpression', | ||
object: {type: 'Identifier', name: 'MDXContent'}, | ||
property: {type: 'Identifier', name: 'isMDXComponent'}, | ||
computed: false, | ||
optional: false | ||
}, | ||
right: {type: 'Literal', value: true, raw: 'true'} | ||
} | ||
} | ||
] | ||
} | ||
function serializeEsSyntax(node) { | ||
return node.value | ||
function createMdxLayout(declaration, mdxLayoutDefault) { | ||
const id = {type: 'Identifier', name: 'MDXLayout'} | ||
const init = {type: 'Literal', value: 'wrapper', raw: '"wrapper"'} | ||
return [ | ||
mdxLayoutDefault | ||
? { | ||
type: 'ImportDeclaration', | ||
specifiers: [ | ||
mdxLayoutDefault.local.name === 'default' | ||
? {type: 'ImportDefaultSpecifier', local: id} | ||
: { | ||
type: 'ImportSpecifier', | ||
imported: mdxLayoutDefault.local, | ||
local: id | ||
} | ||
], | ||
source: { | ||
type: 'Literal', | ||
value: mdxLayoutDefault.source.value, | ||
raw: mdxLayoutDefault.source.raw | ||
} | ||
} | ||
: { | ||
type: 'VariableDeclaration', | ||
declarations: [ | ||
{type: 'VariableDeclarator', id: id, init: declaration || init} | ||
], | ||
kind: 'const' | ||
} | ||
] | ||
} | ||
function serializeChildren(node, options) { | ||
const children = node.children || [] | ||
const childOptions = Object.assign({}, options, { | ||
// Tell all children inside <pre> tags to preserve newlines as text nodes | ||
preserveNewlines: options.preserveNewlines || node.tagName === 'pre' | ||
}) | ||
function createMakeShortcodeHelper(names, useElement) { | ||
const func = { | ||
type: 'VariableDeclaration', | ||
declarations: [ | ||
{ | ||
type: 'VariableDeclarator', | ||
id: {type: 'Identifier', name: 'makeShortcode'}, | ||
init: { | ||
type: 'ArrowFunctionExpression', | ||
id: null, | ||
expression: true, | ||
generator: false, | ||
async: false, | ||
params: [{type: 'Identifier', name: 'name'}], | ||
body: { | ||
type: 'ArrowFunctionExpression', | ||
id: null, | ||
expression: false, | ||
generator: false, | ||
async: false, | ||
params: [{type: 'Identifier', name: 'props'}], | ||
body: { | ||
type: 'BlockStatement', | ||
body: [ | ||
{ | ||
type: 'ExpressionStatement', | ||
expression: { | ||
type: 'CallExpression', | ||
callee: { | ||
type: 'MemberExpression', | ||
object: {type: 'Identifier', name: 'console'}, | ||
property: {type: 'Identifier', name: 'warn'}, | ||
computed: false, | ||
optional: false | ||
}, | ||
arguments: [ | ||
{ | ||
type: 'Literal', | ||
value: | ||
'Component `%s` was not imported, exported, or provided by MDXProvider as global scope' | ||
}, | ||
{type: 'Identifier', name: 'name'} | ||
] | ||
} | ||
}, | ||
{ | ||
type: 'ReturnStatement', | ||
argument: useElement | ||
? { | ||
type: 'JSXElement', | ||
openingElement: { | ||
type: 'JSXOpeningElement', | ||
attributes: [ | ||
{ | ||
type: 'JSXSpreadAttribute', | ||
argument: {type: 'Identifier', name: 'props'} | ||
} | ||
], | ||
name: {type: 'JSXIdentifier', name: 'div'}, | ||
selfClosing: true | ||
}, | ||
closingElement: null, | ||
children: [] | ||
} | ||
: { | ||
type: 'JSXFragment', | ||
openingFragment: {type: 'JSXOpeningFragment'}, | ||
closingFragment: {type: 'JSXClosingFragment'}, | ||
children: [ | ||
{ | ||
type: 'JSXExpressionContainer', | ||
expression: { | ||
type: 'MemberExpression', | ||
object: {type: 'Identifier', name: 'props'}, | ||
property: {type: 'Identifier', name: 'children'}, | ||
computed: false | ||
} | ||
} | ||
] | ||
} | ||
} | ||
] | ||
} | ||
} | ||
} | ||
} | ||
], | ||
kind: 'const' | ||
} | ||
return children | ||
.map(childNode => { | ||
return toJSX(childNode, node, childOptions) | ||
}) | ||
.join('\n') | ||
} | ||
const shortcodes = names.map(name => ({ | ||
type: 'VariableDeclaration', | ||
declarations: [ | ||
{ | ||
type: 'VariableDeclarator', | ||
id: {type: 'Identifier', name: String(name)}, | ||
init: { | ||
type: 'CallExpression', | ||
callee: {type: 'Identifier', name: 'makeShortcode'}, | ||
arguments: [{type: 'Literal', value: String(name)}] | ||
} | ||
} | ||
], | ||
kind: 'const' | ||
})) | ||
// We only do this for the props, so we’re ignoring children. | ||
function fakeReactCreateElement(name, props) { | ||
return { | ||
type: name, | ||
props: props, | ||
// Needed for `toH` to think this is React. | ||
key: null, | ||
_owner: null | ||
} | ||
return shortcodes.length > 0 ? [func, ...shortcodes] : [] | ||
} |
{ | ||
"name": "@mdx-js/mdx", | ||
"version": "2.0.0-next.8", | ||
"version": "2.0.0-next.9", | ||
"description": "Parse MDX and transpile to JSX", | ||
@@ -25,6 +25,7 @@ "repository": "mdx-js/mdx", | ||
"index.js", | ||
"util.js", | ||
"estree-to-js.js", | ||
"mdx-ast-to-mdx-hast.js", | ||
"mdx-hast-to-jsx.js", | ||
"types/index.d.ts", | ||
"util.js" | ||
"types/index.d.ts" | ||
], | ||
@@ -40,28 +41,29 @@ "keywords": [ | ||
"scripts": { | ||
"test-types": "dtslint types" | ||
"test-api": "jest test", | ||
"test-coverage": "jest test --coverage", | ||
"test-types": "dtslint types", | ||
"test": "yarn test-coverage && yarn test-types" | ||
}, | ||
"dependencies": { | ||
"@babel/core": "7.10.5", | ||
"@babel/plugin-syntax-jsx": "7.10.4", | ||
"@babel/plugin-syntax-object-rest-spread": "7.8.3", | ||
"@mdx-js/util": "^2.0.0-next.8", | ||
"babel-plugin-apply-mdx-type-prop": "^2.0.0-next.8", | ||
"babel-plugin-extract-export-names": "^2.0.0-next.8", | ||
"babel-plugin-extract-import-names": "^2.0.0-next.8", | ||
"camelcase-css": "2.0.1", | ||
"detab": "2.0.3", | ||
"hast-to-hyperscript": "9.0.0", | ||
"hast-util-raw": "6.0.0", | ||
"lodash.uniq": "4.5.0", | ||
"mdast-util-to-hast": "9.1.0", | ||
"remark-footnotes": "1.0.0", | ||
"remark-mdx": "^2.0.0-next.8", | ||
"remark-mdxjs": "^2.0.0-next.8", | ||
"remark-parse": "8.0.2", | ||
"remark-squeeze-paragraphs": "4.0.0", | ||
"unified": "9.0.0", | ||
"unist-builder": "2.0.3", | ||
"unist-util-visit": "2.0.3" | ||
"@mdx-js/util": "2.0.0-next.1", | ||
"astring": "^1.4.0", | ||
"detab": "^2.0.0", | ||
"estree-walker": "^2.0.0", | ||
"hast-util-to-estree": "^1.1.0", | ||
"mdast-util-to-hast": "^10.1.0", | ||
"periscopic": "^2.0.0", | ||
"rehype-minify-whitespace": "^4.0.0", | ||
"remark-mdx": "2.0.0-next.9", | ||
"remark-parse": "^9.0.0", | ||
"remark-squeeze-paragraphs": "^4.0.0", | ||
"unified": "^9.2.0", | ||
"unist-builder": "^2.0.0" | ||
}, | ||
"gitHead": "e194fc1a61715549be10d56055ea4ad25533fcb1" | ||
"devDependencies": { | ||
"rehype-katex": "^4.0.0", | ||
"remark-footnotes": "^3.0.0", | ||
"remark-gfm": "^1.0.0", | ||
"remark-math": "^4.0.0" | ||
}, | ||
"gitHead": "6fc71ff94c671582b4185a98f87dcdb1d18c831b" | ||
} |
# `@mdx-js/mdx` | ||
[![Build Status][build-badge]][build] | ||
[![lerna][lerna-badge]][lerna] | ||
[![Join the community on Spectrum][spectrum-badge]][spectrum] | ||
[![Chat][chat-badge]][chat] | ||
@@ -57,6 +56,4 @@ [MDX][] implementation using [remark][]. | ||
[build-badge]: https://travis-ci.com/mdx-js/mdx.svg?branch=master | ||
[lerna]: https://lernajs.io/ | ||
[lerna-badge]: https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg | ||
[spectrum]: https://spectrum.chat/mdx | ||
[spectrum-badge]: https://withspectrum.github.io/badge/badge.svg | ||
[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg | ||
[chat]: https://github.com/mdx-js/mdx/discussions | ||
[contributing]: https://mdxjs.com/contributing | ||
@@ -63,0 +60,0 @@ [support]: https://mdxjs.com/support |
@@ -8,7 +8,6 @@ // TypeScript Version: 3.4 | ||
/** | ||
* support footnotes | ||
* | ||
* @default true | ||
* Path on disk to processed file | ||
* @default undefined | ||
*/ | ||
footnotes?: boolean | ||
filepath?: string | ||
@@ -41,9 +40,2 @@ /** | ||
rehypePlugins?: Plugin[] | ||
/** | ||
* compilers to customize output | ||
* | ||
* @default [] | ||
*/ | ||
compilers?: Compiler[] | ||
} | ||
@@ -50,0 +42,0 @@ |
@@ -1,3 +0,2 @@ | ||
// For backwards compatibility with downstream users | ||
// of MDX utilities | ||
console.warn('@mdx-js/util is deprecated: please update the code using it') | ||
module.exports = require('@mdx-js/util') |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
24586
13
9
647
4
67
1
+ Addedastring@^1.4.0
+ Addedestree-walker@^2.0.0
+ Addedhast-util-to-estree@^1.1.0
+ Addedperiscopic@^2.0.0
+ Added@mdx-js/util@2.0.0-next.1(transitive)
+ Addedastring@1.8.6(transitive)
+ Addedcharacter-entities-html4@1.1.4(transitive)
+ Addeddebug@4.3.4(transitive)
+ Addeddetab@2.0.4(transitive)
+ Addedestree-util-attach-comments@1.0.0(transitive)
+ Addedestree-util-is-identifier-name@1.1.0(transitive)
+ Addedestree-walker@2.0.2(transitive)
+ Addedhast-util-embedded@1.0.6(transitive)
+ Addedhast-util-is-element@1.1.0(transitive)
+ Addedhast-util-to-estree@1.4.0(transitive)
+ Addedhast-util-whitespace@1.0.4(transitive)
+ Addedis-reference@1.2.1(transitive)
+ Addedlongest-streak@2.0.4(transitive)
+ Addedmdast-util-definitions@4.0.0(transitive)
+ Addedmdast-util-from-markdown@0.8.5(transitive)
+ Addedmdast-util-mdx@0.1.1(transitive)
+ Addedmdast-util-mdx-expression@0.1.1(transitive)
+ Addedmdast-util-mdx-jsx@0.1.4(transitive)
+ Addedmdast-util-mdxjs-esm@0.1.1(transitive)
+ Addedmdast-util-to-hast@10.2.0(transitive)
+ Addedmdast-util-to-markdown@0.6.5(transitive)
+ Addedmdast-util-to-string@2.0.0(transitive)
+ Addedmicromark@2.11.4(transitive)
+ Addedmicromark-extension-mdx@0.2.1(transitive)
+ Addedmicromark-extension-mdx-expression@0.3.2(transitive)
+ Addedmicromark-extension-mdx-jsx@0.3.3(transitive)
+ Addedmicromark-extension-mdx-md@0.1.1(transitive)
+ Addedmicromark-extension-mdxjs@0.3.0(transitive)
+ Addedmicromark-extension-mdxjs-esm@0.3.1(transitive)
+ Addedmin-indent@1.0.1(transitive)
+ Addedperiscopic@2.0.3(transitive)
+ Addedrehype-minify-whitespace@4.0.5(transitive)
+ Addedremark-mdx@2.0.0-next.9(transitive)
+ Addedremark-parse@9.0.0(transitive)
+ Addedstringify-entities@3.1.0(transitive)
+ Addedstrip-indent@3.0.0(transitive)
+ Addedunified@9.2.2(transitive)
+ Addedunist-util-remove-position@3.0.0(transitive)
- Removed@babel/core@7.10.5
- Removed@babel/plugin-syntax-jsx@7.10.4
- Removedcamelcase-css@2.0.1
- Removedhast-to-hyperscript@9.0.0
- Removedhast-util-raw@6.0.0
- Removedlodash.uniq@4.5.0
- Removedremark-footnotes@1.0.0
- Removedremark-mdxjs@^2.0.0-next.8
- Removedunist-util-visit@2.0.3
- Removed@babel/code-frame@7.24.6(transitive)
- Removed@babel/core@7.10.5(transitive)
- Removed@babel/generator@7.24.6(transitive)
- Removed@babel/helper-environment-visitor@7.24.6(transitive)
- Removed@babel/helper-function-name@7.24.6(transitive)
- Removed@babel/helper-hoist-variables@7.24.6(transitive)
- Removed@babel/helper-module-imports@7.24.6(transitive)
- Removed@babel/helper-module-transforms@7.24.6(transitive)
- Removed@babel/helper-plugin-utils@7.10.47.24.6(transitive)
- Removed@babel/helper-simple-access@7.24.6(transitive)
- Removed@babel/helper-split-export-declaration@7.24.6(transitive)
- Removed@babel/helper-string-parser@7.24.6(transitive)
- Removed@babel/helper-validator-identifier@7.24.6(transitive)
- Removed@babel/helpers@7.24.6(transitive)
- Removed@babel/highlight@7.24.6(transitive)
- Removed@babel/parser@7.24.6(transitive)
- Removed@babel/plugin-proposal-object-rest-spread@7.10.4(transitive)
- Removed@babel/plugin-syntax-jsx@7.10.4(transitive)
- Removed@babel/plugin-syntax-object-rest-spread@7.8.3(transitive)
- Removed@babel/plugin-transform-parameters@7.24.6(transitive)
- Removed@babel/template@7.24.6(transitive)
- Removed@babel/traverse@7.24.6(transitive)
- Removed@babel/types@7.24.6(transitive)
- Removed@jridgewell/gen-mapping@0.3.5(transitive)
- Removed@jridgewell/resolve-uri@3.1.2(transitive)
- Removed@jridgewell/set-array@1.2.1(transitive)
- Removed@jridgewell/sourcemap-codec@1.4.15(transitive)
- Removed@jridgewell/trace-mapping@0.3.25(transitive)
- Removed@mdx-js/util@2.0.0-next.8(transitive)
- Removed@types/acorn@4.0.6(transitive)
- Removed@types/debug@4.1.12(transitive)
- Removed@types/estree-jsx@1.0.5(transitive)
- Removed@types/hast@2.3.10(transitive)
- Removed@types/ms@0.7.34(transitive)
- Removed@types/parse5@5.0.3(transitive)
- Removedansi-styles@3.2.1(transitive)
- Removedbabel-plugin-apply-mdx-type-prop@2.0.0-next.8(transitive)
- Removedbabel-plugin-extract-export-names@2.0.0-next.8(transitive)
- Removedbabel-plugin-extract-import-names@2.0.0-next.8(transitive)
- Removedcamelcase-css@2.0.1(transitive)
- Removedccount@1.1.02.0.1(transitive)
- Removedchalk@2.4.2(transitive)
- Removedcharacter-entities@2.0.2(transitive)
- Removedcharacter-entities-html4@2.1.0(transitive)
- Removedcharacter-entities-legacy@3.0.0(transitive)
- Removedcharacter-reference-invalid@2.0.1(transitive)
- Removedcollapse-white-space@1.0.6(transitive)
- Removedcolor-convert@1.9.3(transitive)
- Removedcolor-name@1.1.3(transitive)
- Removedconvert-source-map@1.9.0(transitive)
- Removeddebug@4.3.5(transitive)
- Removeddecode-named-character-reference@1.0.2(transitive)
- Removeddequal@2.0.3(transitive)
- Removeddetab@2.0.3(transitive)
- Removeddiff@5.2.0(transitive)
- Removedescape-string-regexp@1.0.5(transitive)
- Removedestree-util-is-identifier-name@2.1.0(transitive)
- Removedestree-util-visit@1.2.1(transitive)
- Removedfunction-bind@1.1.2(transitive)
- Removedgensync@1.0.0-beta.2(transitive)
- Removedglobals@11.12.0(transitive)
- Removedhas-flag@3.0.0(transitive)
- Removedhasown@2.0.2(transitive)
- Removedhast-to-hyperscript@9.0.0(transitive)
- Removedhast-util-from-parse5@6.0.1(transitive)
- Removedhast-util-parse-selector@2.2.5(transitive)
- Removedhast-util-raw@6.0.0(transitive)
- Removedhast-util-to-parse5@6.0.0(transitive)
- Removedhastscript@6.0.0(transitive)
- Removedhtml-void-elements@1.0.5(transitive)
- Removedinherits@2.0.4(transitive)
- Removedis-alphabetical@2.0.1(transitive)
- Removedis-alphanumerical@2.0.1(transitive)
- Removedis-core-module@2.13.1(transitive)
- Removedis-decimal@2.0.1(transitive)
- Removedis-hexadecimal@2.0.1(transitive)
- Removedis-whitespace-character@1.0.4(transitive)
- Removedis-word-character@1.0.4(transitive)
- Removedjs-tokens@4.0.0(transitive)
- Removedjsesc@2.5.2(transitive)
- Removedjson5@2.2.3(transitive)
- Removedkleur@4.1.5(transitive)
- Removedlodash@4.17.21(transitive)
- Removedlodash.uniq@4.5.0(transitive)
- Removedlongest-streak@3.1.0(transitive)
- Removedmarkdown-escapes@1.0.4(transitive)
- Removedmdast-util-definitions@3.0.1(transitive)
- Removedmdast-util-from-markdown@1.3.1(transitive)
- Removedmdast-util-mdx@2.0.1(transitive)
- Removedmdast-util-mdx-expression@1.3.2(transitive)
- Removedmdast-util-mdx-jsx@2.1.4(transitive)
- Removedmdast-util-mdxjs-esm@1.3.1(transitive)
- Removedmdast-util-phrasing@3.0.1(transitive)
- Removedmdast-util-to-hast@9.1.0(transitive)
- Removedmdast-util-to-markdown@1.5.0(transitive)
- Removedmdast-util-to-string@3.2.0(transitive)
- Removedmicromark@3.2.0(transitive)
- Removedmicromark-core-commonmark@1.1.0(transitive)
- Removedmicromark-extension-mdx-expression@1.0.8(transitive)
- Removedmicromark-extension-mdx-jsx@1.0.5(transitive)
- Removedmicromark-extension-mdx-md@1.0.1(transitive)
- Removedmicromark-extension-mdxjs@1.0.1(transitive)
- Removedmicromark-extension-mdxjs-esm@1.0.5(transitive)
- Removedmicromark-factory-destination@1.1.0(transitive)
- Removedmicromark-factory-label@1.1.0(transitive)
- Removedmicromark-factory-mdx-expression@1.0.9(transitive)
- Removedmicromark-factory-space@1.1.0(transitive)
- Removedmicromark-factory-title@1.1.0(transitive)
- Removedmicromark-factory-whitespace@1.1.0(transitive)
- Removedmicromark-util-character@1.2.0(transitive)
- Removedmicromark-util-chunked@1.1.0(transitive)
- Removedmicromark-util-classify-character@1.1.0(transitive)
- Removedmicromark-util-combine-extensions@1.1.0(transitive)
- Removedmicromark-util-decode-numeric-character-reference@1.1.0(transitive)
- Removedmicromark-util-decode-string@1.1.0(transitive)
- Removedmicromark-util-encode@1.1.0(transitive)
- Removedmicromark-util-events-to-acorn@1.2.3(transitive)
- Removedmicromark-util-html-tag-name@1.2.0(transitive)
- Removedmicromark-util-normalize-identifier@1.1.0(transitive)
- Removedmicromark-util-resolve-all@1.1.0(transitive)
- Removedmicromark-util-sanitize-uri@1.2.0(transitive)
- Removedmicromark-util-subtokenize@1.1.0(transitive)
- Removedmicromark-util-symbol@1.1.0(transitive)
- Removedmicromark-util-types@1.1.0(transitive)
- Removedmri@1.2.0(transitive)
- Removedparse-entities@4.0.1(transitive)
- Removedparse5@6.0.1(transitive)
- Removedpath-parse@1.0.7(transitive)
- Removedpicocolors@1.0.1(transitive)
- Removedremark-footnotes@1.0.0(transitive)
- Removedremark-mdx@2.3.0(transitive)
- Removedremark-mdxjs@2.0.0-next.8(transitive)
- Removedremark-parse@8.0.2(transitive)
- Removedresolve@1.22.8(transitive)
- Removedsade@1.8.1(transitive)
- Removedsemver@5.7.2(transitive)
- Removedsource-map@0.5.7(transitive)
- Removedstate-toggle@1.0.3(transitive)
- Removedstringify-entities@4.0.4(transitive)
- Removedsupports-color@5.5.0(transitive)
- Removedsupports-preserve-symlinks-flag@1.0.0(transitive)
- Removedto-fast-properties@2.0.0(transitive)
- Removedtrim@0.0.1(transitive)
- Removedtrim-lines@1.1.3(transitive)
- Removedtrim-trailing-lines@1.1.4(transitive)
- Removedunherit@1.1.3(transitive)
- Removedunified@9.0.0(transitive)
- Removedunist-util-is@5.2.1(transitive)
- Removedunist-util-position-from-estree@1.1.2(transitive)
- Removedunist-util-remove-position@2.0.14.0.2(transitive)
- Removedunist-util-stringify-position@3.0.3(transitive)
- Removedunist-util-visit@4.1.2(transitive)
- Removedunist-util-visit-parents@5.1.3(transitive)
- Removeduvu@0.5.6(transitive)
- Removedvfile-location@3.2.0(transitive)
- Removedvfile-message@3.1.4(transitive)
- Removedweb-namespaces@1.1.4(transitive)
- Removedzwitch@2.0.4(transitive)
Updated@mdx-js/util@2.0.0-next.1
Updateddetab@^2.0.0
Updatedmdast-util-to-hast@^10.1.0
Updatedremark-mdx@2.0.0-next.9
Updatedremark-parse@^9.0.0
Updatedunified@^9.2.0
Updatedunist-builder@^2.0.0