1
1
mirror of https://github.com/mdx-js/mdx.git synced 2024-10-03 19:07:42 +03:00

Miscellaneous cleaning tasks (#1677)

* Add `remark-cli`, `prettier` back
* Update license years
* Reorder `package.json`
* Update `.gitignore`
* Update `.editorconfig`
* Remove `.gitattributes`
* Remove unneeded babel files
This commit is contained in:
Titus 2021-09-24 12:58:28 +02:00 committed by GitHub
parent 6029a14f24
commit 2b806ae902
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
106 changed files with 6335 additions and 6706 deletions

View File

@ -1,10 +1,9 @@
# https://editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true

7
.gitattributes vendored
View File

@ -1,7 +0,0 @@
*.js text eol=lf
*.json text eol=lf
*.jsx text eol=lf
*.md text eol=lf
*.mdx text eol=lf
*.ts text eol=lf
*.tsx text eol=lf

View File

@ -6,6 +6,8 @@ jobs:
main:
name: '${{matrix.os}} / ${{matrix.node}}'
runs-on: ${{matrix.os}}
env:
PUPPETEER_SKIP_DOWNLOAD: 1
steps:
- uses: actions/checkout@v2
with:

23
.gitignore vendored
View File

@ -1,18 +1,14 @@
node_modules
dist
cache
build
.next
*-error.log
*-debug.log
.vscode
.parcel-cache/
.DS_Store
tmp
artifacts
.*cache
.nyc_output/
.eslintcache
coverage/
/public
node_modules/
/examples/next/build/
/examples/next/.next/
/examples/parcel/dist/
/examples/parcel/build/
/examples/react-web-components/build/
/examples/react-web-components/.next/
/packages/loader/lib/**/*.d.ts
/packages/loader/test/**/*.d.ts
/packages/mdx/**/*.d.ts
@ -27,3 +23,4 @@ coverage/
/packages/vue/lib/**/*.d.ts
/packages/vue/test/**/*.d.ts
/packages/vue/index.d.ts
/public

View File

@ -1,11 +1,12 @@
.cache/
.next/
build/
coverage/
dist/
fixtures/
examples/gatsby/.cache/
examples/next/.next/
examples/next/build/
examples/parcel/build/
examples/parcel/dist/
examples/react-web-components/.next/
examples/react-web-components/build/
node_modules/
coverage/
public/
*.min.*
*.md
*.mdx

1
.remarkignore Normal file
View File

@ -0,0 +1 @@
packages/remark-mdx/test/fixtures/

View File

@ -1,8 +0,0 @@
module.exports = {
plugins: [
'remark-frontmatter',
'preset-wooorm',
'preset-prettier',
['retext', false]
]
}

View File

@ -5,5 +5,5 @@ export const navExclude = true
Aww, snap.
Unfortunately this page doesnt exist.
Perhaps you can find what youre looking for on [on
Perhaps you can find what youre looking for [on
GitHub](https://github.com/mdx-js/mdx/search)?

View File

@ -1,19 +0,0 @@
## Babel configuration
You will also need to configure [babel][] to support the language features that
MDX uses. One way you can achieve that is using the following `.babelrc`
at your project root.
```json
{
"presets": ["@babel/env", "@babel/react"]
}
```
And installing the dependencies:
```sh
npm install --save-dev @babel/preset-env @babel/preset-react
```
[babel]: https://babeljs.io

View File

@ -74,9 +74,7 @@ export function NavItem(props) {
) : (
defaultTitle
)}
{navLabel ? (
<sup>[{navLabel}]</sup>
) : null}
{navLabel ? <sup>[{navLabel}]</sup> : null}
{includeDescription && description ? ' — ' + description : null}
{includePublished && published
? ' — ' + dateTimeFormat.format(published)

View File

@ -1,8 +1,10 @@
# About
MDX is based on the [original `.mdx` proposal][idea] by Guillermo Rauch
([@rauchg][rauchg]). Its syntax is defined by an official [specification][].
The source code for MDX is available on [GitHub][] and is [MIT licensed][license].
([@rauchg][rauchg]).
Its syntax is defined by an official [specification][].
The source code for MDX is available on [GitHub][] and is
[MIT licensed][license].
The project is governed by the [unified collective][governance].
@ -13,10 +15,10 @@ also available on [GitHub][design].
### Authors
- [John Otander][john] ([@4lpine][4lpine]) [Components AI](https://components.ai)
- [Tim Neutkens][tim] ([@timneutkens][timneutkens]) [Vercel][]
- [Guillermo Rauch][guillermo] ([@rauchg][rauchg]) [Vercel][]
- [Brent Jackson][brent] ([@jxnblk][jxnblk]) [Gatsby](https://gatsbyjs.com)
* [John Otander][john] ([@4lpine][4lpine]) [Components AI](https://components.ai)
* [Tim Neutkens][tim] ([@timneutkens][timneutkens]) [Vercel][]
* [Guillermo Rauch][guillermo] ([@rauchg][rauchg]) [Vercel][]
* [Brent Jackson][brent] ([@jxnblk][jxnblk]) [Gatsby](https://gatsbyjs.com)
## Related
@ -31,43 +33,58 @@ PR!
These projects define the syntax which MDX blends together (MD and JSX).
- [Markdown](https://daringfireball.net/projects/markdown/syntax)
- [JSX](https://reactjs.org/docs/introducing-jsx.html)
- [React](https://reactjs.org/)
* [Markdown](https://daringfireball.net/projects/markdown/syntax)
* [JSX](https://reactjs.org/docs/introducing-jsx.html)
* [React](https://reactjs.org/)
### Parsing and implementation
- [remark](https://remark.js.org)
- [unified](https://unifiedjs.com)
- [babel](https://babeljs.io)
* [remark](https://remark.js.org)
* [unified](https://unifiedjs.com)
* [babel](https://babeljs.io)
### Libraries
- [MDXC](https://github.com/jamesknelson/mdxc)
- [Markdown Component Loader](https://github.com/ticky/markdown-component-loader)
- [markdown-in-js](https://github.com/threepointone/markdown-in-js)
- [remark-jsx](https://github.com/fazouane-marouane/remark-jsx)
- [remark-react](https://github.com/mapbox/remark-react)
- [eslint-mdx](https://github.com/rx-ts/eslint-mdx)
* [MDXC](https://github.com/jamesknelson/mdxc)
* [Markdown Component Loader](https://github.com/ticky/markdown-component-loader)
* [markdown-in-js](https://github.com/threepointone/markdown-in-js)
* [remark-jsx](https://github.com/fazouane-marouane/remark-jsx)
* [remark-react](https://github.com/mapbox/remark-react)
* [eslint-mdx](https://github.com/rx-ts/eslint-mdx)
### Other
- [IA Markdown Content Blocks](https://github.com/iainc/Markdown-Content-Blocks)
- [Idyll: Markup language for interactive documents](https://idyll-lang.org)
* [IA Markdown Content Blocks](https://github.com/iainc/Markdown-Content-Blocks)
* [Idyll: Markup language for interactive documents](https://idyll-lang.org)
[github]: https://github.com/mdx-js/mdx
[license]: https://github.com/mdx-js/mdx/blob/master/license
[specification]: https://github.com/mdx-js/specification
[governance]: https://github.com/unifiedjs/collective
[design]: https://github.com/mdx-js/design
[idea]: https://spectrum.chat/thread/1021be59-2738-4511-aceb-c66921050b9a
[john]: https://johno.com
[tim]: https://github.com/timneutkens
[guillermo]: https://rauchg.com
[brent]: https://jxnblk.com
[4lpine]: https://twitter.com/4lpine
[rauchg]: https://twitter.com/rauchg
[timneutkens]: https://twitter.com/timneutkens
[jxnblk]: https://twitter.com/jxnblk
[evil rabbit]: https://twitter.com/evilrabbit_
[vercel]: https://vercel.com

View File

@ -11,6 +11,10 @@ the JSX string is created.
## Contents
* [Async API](#async-api)
* [Sync API](#sync-api)
* [Compiler](#compiler)
## Async API
By default, MDX is [asynchronous][async] because plugins can be asynchronous
@ -111,7 +115,9 @@ const mdxText = fs.readFileSync('hello.mdx', 'utf8')
const jsx = mdx.sync(mdxText)
```
MDXs [runtime][] package has [example][] usage.
{/* To do: add link to runtime. */}
MDXs [runtime][] package has example usage.
## Compiler
@ -156,8 +162,11 @@ mdxCompiler.process(file, function done(err, file) {
```
[ast]: /advanced/ast
[plugins]: /plugins
[async]: #async-api
[sync]: #sync-api
[runtime]: /advanced/runtime
[example]: https://github.com/mdx-js/mdx/blob/d5a5189e715dc28370de13f6cc0fd18a06f0f122/packages/runtime/src/index.js#L16-L18

View File

@ -1,19 +1,14 @@
export const AST_EXPLORER_LINK =
'https://astexplorer.net/#/gist/2befce6edce1475eb4bbec001356b222/35997d3b44347daabad8dd1a107adc22dd873de2'
# AST
<a href={AST_EXPLORER_LINK}>
Explore the AST
</a>
[Explore the AST](https://astexplorer.net/#/gist/2befce6edce1475eb4bbec001356b222/35997d3b44347daabad8dd1a107adc22dd873de2)
<a href="/playground">
Use the Playground
</a>
[Use the Playground](/playground")
MDX, the library, uses two syntax trees.
The first, [MDXAST][], represents markdown with embedded JSX, and is a superset of [mdast][].
The second, [MDXHAST][], represent HTML with embedded JSX, and is a superset of [hast][].
The first, [MDXAST][], represents markdown with embedded JSX, and is a superset
of [mdast][].
The second, [MDXHAST][], represent HTML with embedded JSX, and is a superset of
[hast][].
MDX includes a [specification][] to define the syntax and transpilation.
Its based on the [remark][]/[rehype][]/[unified][] ecosystems to ensure robust
@ -26,10 +21,10 @@ languages created by the community.
The majority of the MDXAST specification is defined by [mdast][].
MDXAST is a superset with the following additional node types:
- `jsx` (instead of `html`)
- `comment` (instead of `html` comments)
- `import`
- `export`
* `jsx` (instead of `html`)
* `comment` (instead of `html` comments)
* `import`
* `export`
Any MDX document without those constructs is valid [mdast][].
@ -43,21 +38,29 @@ its defined by [hast][] already.
MDXAST defines the following additional node types:
- `jsx` (instead of `html`)
- `import`
- `export`
- `inlineCode`
* `jsx` (instead of `html`)
* `import`
* `export`
* `inlineCode`
`inlineCode` is there to accurately represent Markdowns inline code.
For more information, see the [MDXHAST][] specification.
[mdxast]: #mdxast
[mdxhast]: #mdxhast
[comment]: https://github.com/syntax-tree/hast#comment
[mdast]: https://github.com/syntax-tree/mdast
[hast]: https://github.com/syntax-tree/hast
[specification]: https://github.com/mdx-js/specification
[remark]: https://github.com/remarkjs/remark
[rehype]: https://github.com/rehypejs/rehype
[unified]: https://github.com/unifiedjs/unified

View File

@ -51,18 +51,18 @@ documents via the [MDXProvider](#mdxprovider).
### Layout props
Youll also notice that `layoutProps` is created based on your exports
and then passed to the wrapper. This allows for the wrapper to use
those props automatically for handling things like adding an author
bio to the wrapped document.
and then passed to the wrapper.
This allows for the wrapper to use those props automatically for handling things
like adding an author bio to the wrapped document.
## `makeShortcode`
There is one other function added to the compiled output: `makeShortcode`.
This is added for [shortcode support](/blog/shortcodes). Its used in order
to stub any components that arent directly imported so that there wont be
any `ReferenceError`s. If theyre passed to the `MDXProvider`, the custom
JSX pragma will pull the component from context and use that in place of the
stubbed `Button`:
This is added for [shortcode support](/blog/shortcodes).
Its used in order to stub any components that arent directly imported so that
there wont be any `ReferenceError`s.
If theyre passed to the `MDXProvider`, the custom JSX pragma will pull the
component from context and use that in place of the stubbed `Button`:
```js
const makeShortcode = name =>
@ -101,12 +101,14 @@ export default () => (
### Caveats
Because MDXProvider uses React Context directly, it is affected by
the same caveats. It is therefore important that you do not declare
your components mapping inline in the JSX. Doing so will trigger a rerender
of your entire MDX page with every render cycle. Not only is this bad for
performance, but it can cause unwanted side affects, like breaking in-page
browser navigation.
Because MDXProvider uses React Context directly, it is affected by the same
caveats.
It is therefore important that you do not declare your components mapping inline
in the JSX.
Doing so will trigger a rerender of your entire MDX page with every render
cycle.
Not only is this bad for performance, but it can cause unwanted side affects,
like breaking in-page browser navigation.
Avoid this by following declaring your mapping as a constant.
@ -144,4 +146,4 @@ export default class Layout extends React.Component {
You can now use the `setState` function to update the mapping object and be
assured that it wonʼt trigger unnecessary renders.
[code-generation]: https://en.wikipedia.org/wiki/Code_generation_(compiler)
[code-generation]: https://en.wikipedia.org/wiki/Code_generation_\(compiler\)

View File

@ -10,11 +10,13 @@ directly.
{
(() => {
const advanced = props.navTree.children.find((item) => item.name === '/advanced/')
const category = props.navTree.children.find(
item => item.name === '/advanced/'
)
return (
<nav>
<NavGroup items={advanced.children} includeDescription />
<NavGroup items={category.children} includeDescription />
</nav>
)
})()

View File

@ -25,12 +25,13 @@ table of contents][remark-toc], and many more.
For more information, see the following links:
- [List of remark plugins][remark-plugins]
- [List of rehype plugins][rehype-plugins]
* [List of remark plugins][remark-plugins]
* [List of rehype plugins][rehype-plugins]
Creating a plugin for MDX is mostly the same as creating a plugin for remark
or rehype.
We wrote a guide on how to [write a plugin][write-plugin], and the unified website has another good guide on how to [create a plugin][create-plugin].
We wrote a guide on how to [write a plugin][write-plugin], and the unified
website has another good guide on how to [create a plugin][create-plugin].
To see how the syntax trees in MDX deviate from the syntax trees used in remark
or rehype, see [the docs for the AST][ast].
@ -147,15 +148,27 @@ mdx.sync(mdxText, {
```
[ast]: /advanced/ast
[write-plugin]: /guides/writing-a-plugin
[remark]: https://github.com/remarkjs/remark
[rehype]: https://github.com/rehypejs/rehype
[remark-capitalize]: https://github.com/zeit/remark-capitalize
[remark-toc]: https://github.com/remarkjs/remark-toc
[remark-plugins]: https://github.com/remarkjs/remark/blob/main/doc/plugins.md#list-of-plugins
[rehype-plugins]: https://github.com/rehypejs/rehype/blob/main/doc/plugins.md#list-of-plugins
[retext]: https://github.com/retextjs/retext
[remarkjs/remark#224]: https://github.com/remarkjs/remark/issues/224
[visit]: https://github.com/syntax-tree/unist-util-visit
[retext-smartypants]: https://github.com/retextjs/retext-smartypants
[create-plugin]: https://unifiedjs.com/learn/guide/create-a-plugin

View File

@ -6,9 +6,9 @@ are many utilities you can use to work with MDX.
You can utilize [to-vfile][] to read and write MDX files
and you can leverage [remark][] and [remark-mdx][]
to parse and process MDX content. The remark-mdx library is a parsing
extension to enhance the Markdown [AST][] to understand MDX
(resulting in [MDXAST][]), giving you access and insight to MDX
to parse and process MDX content.
The remark-mdx library is a parsing extension to enhance the Markdown [AST][] to
understand MDX (resulting in [MDXAST][]), giving you access and insight to MDX
attributes, namely imports, exports, and jsx.
Lets see an example of what we have explained so far.
@ -89,12 +89,21 @@ generated table of contents based on the other content in the MDX file or
save the modified content back to the original file.
[ast]: /advanced/ast
[mdxast]: /advanced/ast#mdxast
[remark]: https://github.com/remarkjs/remark
[remark-mdx]: https://github.com/mdx-js/mdx/tree/master/packages/remark-mdx
[remark-mdx-metadata]: https://github.com/manovotny/remark-mdx-metadata
[remark-plugins]: /advanced/plugins
[remark-toc]: https://github.com/remarkjs/remark-toc
[to-vfile]: https://github.com/vfile/to-vfile
[unified]: https://unifiedjs.com
[writing-a-plugin]: /guides/writing-a-plugin

View File

@ -2,17 +2,17 @@
MDX provides typings for many of the core packages.
If you want to improve upon the types, we would _love_ a PR to
If you want to improve upon the types, we would *love* a PR to
improve the developer experience for TypeScript users.
## Typings for Components and Utilities
- `@mdx-js/mdx`
- `@mdx-js/preact`
- `@mdx-js/react`
- `@mdx-js/runtime`
- `@mdx-js/vue`
- `remark-mdx`
* `@mdx-js/mdx`
* `@mdx-js/preact`
* `@mdx-js/react`
* `@mdx-js/runtime`
* `@mdx-js/vue`
* `remark-mdx`
Include types, no additional setup needed.
@ -20,7 +20,8 @@ Include types, no additional setup needed.
### React and Webpack
Add an `mdx.d.ts` file with the below content, and ensure it is included by the `tsconfig.json`.
Add an `mdx.d.ts` file with the below content, and ensure it is included by the
`tsconfig.json`.
```tsx
/// <reference types="@mdx-js/loader" />
@ -28,7 +29,8 @@ Add an `mdx.d.ts` file with the below content, and ensure it is included by the
### Vue and Webpack
Add an `mdx.d.ts` file with the below content, and ensure it is included by the `tsconfig.json`.
Add an `mdx.d.ts` file with the below content, and ensure it is included by the
`tsconfig.json`.
```tsx
/// <reference types="@mdx-js/vue-loader" />

View File

@ -2,7 +2,8 @@
`MDXTag`, for those that arent aware, is a critical piece in the way
MDX replaces HTML primitives like `<pre>` and `<h1>` with custom React
Components. [Ive previously
Components.
[Ive previously
written](https://www.christopherbiscardi.com/post/codeblocks-mdx-and-mdx-utils)
about the way `MDXTag` works when trying to replace the `<pre>` tag
with a custom code component.
@ -37,7 +38,8 @@ exports.preToCodeBlock = preProps => {
```
So `MDXTag` is a real Component in the middle of all of the other MDX
rendered elements. All of the code is included here for reference.
rendered elements.
All of the code is included here for reference.
```js
import React, {Component} from 'react'
@ -82,11 +84,11 @@ class MDXTag extends Component {
export default withMDXComponents(MDXTag)
```
`MDXTag` is used in the [mdx-hast-to-jsx
conversion](https://github.com/mdx-js/mdx/blob/e1bcf1b1a352c9728424b01c1bb5d62e450eb48d/packages/mdx/mdx-hast-to-jsx.js#L163-L165),
which is the final step in the MDX AST pipeline. Every renderable
element is wrapped in an `MDXTag`, and `MDXTag` handles rendering the
element later.
`MDXTag` is used in the [hast to estree
conversion](https://github.com/syntax-tree/hast-util-to-estree),
which is the final step in the MDX AST pipeline.
Every renderable element is wrapped in an `MDXTag`, and `MDXTag` handles
rendering the element later.
```js
return `<MDXTag name="${node.tagName}" components={components}${
@ -168,14 +170,17 @@ Notice how now the React elements are plainly readable without
wrapping `MDXTag`.
Now that weve cleaned up the intermediary representation, we need to
make sure that we have the same functionality as the old
`MDXTag`. This is done through a custom `createElement`
implementation. Typically when using React, we use
`React.createElement` to render the elements on screen. This is even
true if youre using JSX because JSX tags such as `<div>` compile to
`createElement` calls. So this time instead of using
`React.createElement` well be using our own. [Check it out in the MDX
repo](https://github.com/mdx-js/mdx/blob/0506708bed0ac787f605b0a97ef77d1954fa1275/packages/react/src/create-element.js)
make sure that we have the same functionality as the old `MDXTag`.
This is done through a custom `createElement` implementation.
Typically when using React, we use `React.createElement` to render the elements
on screen.
This is even true if youre using JSX because JSX tags such as `<div>` compile
to `createElement` calls.
So this time instead of using `React.createElement` well be using our own.
[Check it out in the MDX
repo](#)
{/* To do: fix this article! */}
Reproduced here is our `createElement` function and the logic for how
we decide whether or not MDX should take over the rendering of the
@ -217,14 +222,14 @@ export default function (type, props) {
## Vue
One really cool application of the new output format using a custom
`createElement` is that we can now write versions of it for Vue and
other frameworks. Since the pragma insertion is the responsibility of
the webpack (or other bundlers) loader, swapping the pragma can be an
option in mdx-loader as long as we have a Vue `createElement` to point
to.
`createElement` is that we can now write versions of it for Vue and other
frameworks.
Since the pragma insertion is the responsibility of the webpack (or other
bundlers) loader, swapping the pragma can be an option in mdx-loader as long as
we have a Vue `createElement` to point to.
---
***
Written by [Chris Biscardi](https://christopherbiscardi.com)
**[&lt; Back to blog](/blog)**
**[\< Back to blog](/blog)**

View File

@ -6,11 +6,13 @@ export const navSortItems = 'navSortSelf,meta.published:desc'
{
(() => {
const blog = props.navTree.children.find((item) => item.name === '/blog/')
const category = props.navTree.children.find(
item => item.name === '/blog/'
)
return (
<nav>
<NavGroup items={blog.children} sort={navSortItems} includePublished />
<NavGroup items={category.children} sort={navSortItems} includePublished />
</nav>
)
})()

View File

@ -1,10 +1,10 @@
# Shortcodes
An exciting new feature in MDX v1 is global shortcodes. This
allows you to expose components to all of your documents in
your app or website. This is a useful feature for common
components like YouTube embeds, Twitter cards, or anything
else frequently used in your documents.
An exciting new feature in MDX v1 is global shortcodes.
This allows you to expose components to all of your documents in your app or
website.
This is a useful feature for common components like YouTube embeds, Twitter
cards, or anything else frequently used in your documents.
If you have an application wrapper for your MDX documents
you can add in components with the `MDXProvider`:
@ -22,10 +22,10 @@ export default ({children}) => (
)
```
Then, any MDX document thats wrapped in `App` has access to
`YouTube`, `Twitter`, and `TomatoBox`. Shortcodes are nothing
more than components, so you can reference them anywhere in an
MDX document with JSX.
Then, any MDX document thats wrapped in `App` has access to `YouTube`,
`Twitter`, and `TomatoBox`.
Shortcodes are nothing more than components, so you can reference them anywhere
in an MDX document with JSX.
`example.mdx`
@ -43,21 +43,18 @@ Heres a YouTube shortcode wrapped in TomatoBox:
</TomatoBox>
```
Thats it. 🎉 🚀
Thats it.
🎉 🚀
<a
href="https://codesandbox.io/s/github/mdx-js/mdx/tree/master/examples/shortcodes"
>
Try it on CodeSandbox
</a>
[Try it on CodeSandbox](https://codesandbox.io/s/github/mdx-js/mdx/tree/master/examples/shortcodes)
---
***
Huge thanks to [Chris Biscardi](https://christopherbiscardi.com)
for building out most of this functionality.
---
***
Written by [John Otander](https://johno.com)
**[&lt; Back to blog](/blog)**
**[\< Back to blog](/blog)**

View File

@ -5,12 +5,17 @@
# MDX goes stable
Its been a year and a half since the first MDX commit and a year since MDX was first announced at
ZEIT Day. MDX is a radical paradigm shift in how to write immersive content using components. Its
an open, [authorable format](https://johno.com/authorable-format) that makes it _fun_ to write again.
Its been a year and a half since the first MDX commit and a year since MDX was
first announced at ZEIT Day.
MDX is a radical paradigm shift in how to write immersive content using
components.
Its an open, [authorable format](https://johno.com/authorable-format) that
makes it *fun* to write again.
Since announcing MDX weve been working on numerous bug fixes, new features, better parsing, and integration
tests. Now, we think its ready. **Were happy to finally release v1!**
Since announcing MDX weve been working on numerous bug fixes, new features,
better parsing, and integration tests.
Now, we think its ready.
**Were happy to finally release v1!**
## 🎉 Whats new?
@ -19,144 +24,174 @@ Heres a rough breakdown on what weve been working on:
### Parsing
MDX document parsing is significantly improved.
We wont get into the nitty gritty here, but weve seen how MDX is used in real-world projects, integrated
the edge cases we came across into our test suite, and now handle JSX, imports, and exports much more
intuitively.
We wont get into the nitty gritty here, but weve seen how MDX is used in
real-world projects, integrated the edge cases we came across into our test
suite, and now handle JSX, imports, and exports much more intuitively.
Please open an issue if you find a case we havent covered!😸
### remark-mdx
`remark-mdx` is the syntactic extension for MDX in remark. It provides the parsing functionality for
MDX as a _[remark](https://github.com/remarkjs/remark) plugin_. That sounds a bit meta. What it means
is that before we had the syntax parsing bits _in_ the library (unusable from the outside), and now its
externalized (usable from the outside). This is useful if you want to inspect or transform MDX documents.
For example, it allows tools like prettier to use the exact same parser used by MDX core. Or you could
use `remark-mdx` in combination with [remark-lint](https://github.com/remarkjs/remark-lint) to check your
MDX.
`remark-mdx` is the syntactic extension for MDX in remark.
It provides the parsing functionality for MDX as a
*[remark](https://github.com/remarkjs/remark) plugin*.
That sounds a bit meta.
What it means is that before we had the syntax parsing bits *in* the library
(unusable from the outside), and now its externalized (usable from the
outside).
This is useful if you want to inspect or transform MDX documents.
For example, it allows tools like prettier to use the exact same parser used by
MDX core.
Or you could use `remark-mdx` in combination with
[remark-lint](https://github.com/remarkjs/remark-lint) to check your MDX.
### Custom pragma
With v1 weve moved away from using `MDXTag` and are using a custom pragma which wraps `React.createElement`.
We decided to update this approach so the JSX output is more legible, lighterweight, and more customizable.
**This means MDX can be used with any React, Vue, Preact, or any other library with JSX support**.
With v1 weve moved away from using `MDXTag` and are using a custom pragma which
wraps `React.createElement`.
We decided to update this approach so the JSX output is more legible,
lighterweight, and more customizable.
**This means MDX can be used with any React, Vue, Preact, or any other library
with JSX support**.
Special thanks to [@christopherbiscardi](https://github.com/christopherbiscardi) for implementing this feature.
Special thanks to [@christopherbiscardi](https://github.com/christopherbiscardi)
for implementing this feature.
[Read the blog post](/blog/custom-pragma)
### 📚 Documentation
**Good libraries need great docs**, so weve been working on adding content and improving the overall documentation
website experience.
**Good libraries need great docs**, so weve been working on adding content and
improving the overall documentation website experience.
- [Search (thanks Algolia)](https://mobile.twitter.com/4lpine/status/1114270174096412672)
- [Guides](https://mdxjs.com)
- [Automatic deployment via ZEIT](https://zeit.co)
- [Custom Gatsby theme](https://gatsbyjs.org)
- Reorganization of docs for intuitiveness
- Full page rewrites to improve clarity
* [Search (thanks Algolia)](https://mobile.twitter.com/4lpine/status/1114270174096412672)
* [Guides](https://mdxjs.com)
* [Automatic deployment via ZEIT](https://zeit.co)
* [Custom Gatsby theme](https://gatsbyjs.org)
* Reorganization of docs for intuitiveness
* Full page rewrites to improve clarity
Special thanks to [@jxnblk](https://github.com/jxnblks) and [@wooorm](https://github.com/wooorm) for their help
improving the docs and updating the build tooling.
Special thanks to [@jxnblk](https://github.com/jxnblks) and
[@wooorm](https://github.com/wooorm) for their help improving the docs and
updating the build tooling.
## Breaking changes
In order to make some improvements we were forced to introduce a few breaking changes. **These were the
result of real-world production testing and feedback**. The community has evolved and weve come up with
newer, better ideas over the last year. We have made sure the impact is small and have written a full
migration guide.
In order to make some improvements we were forced to introduce a few breaking
changes.
**These were the result of real-world production testing and feedback**.
The community has evolved and weve come up with newer, better ideas over the
last year.
We have made sure the impact is small and have written a full migration guide.
- 🚨`@mdx-js/tag` is replaced by `@mdx-js/react` and an `@mdx` pragma - [migration guide](/migrating/v1#pragma)
- MDXProvider now merges component contexts when nested - [migration guide](/migrating/v1#mdxprovider)
- React support now requires `>= 16.8` in `@mdx-js/react` - [migration guide](/migrating/v1#react)
* 🚨`@mdx-js/tag` is replaced by `@mdx-js/react` and an `@mdx` pragma
— [migration guide](/migrating/v1#pragma)
* MDXProvider now merges component contexts when nested
— [migration guide](/migrating/v1#mdxprovider)
* React support now requires `>= 16.8` in `@mdx-js/react`
— [migration guide](/migrating/v1#react)
[Read the full v1 migration guide](/migrating/v1)
#### Deprecations
We only needed to introduce one deprecation. The `mdPlugins` and `hastPlugins` options have been renamed
`remarkPlugins` and `rehypePlugins` respectively. For the time being we will issue a warning when the old options
are used. In v2, the old options will be removed.
We only needed to introduce one deprecation.
The `mdPlugins` and `hastPlugins` options have been renamed `remarkPlugins` and
`rehypePlugins` respectively.
For the time being we will issue a warning when the old options are used.
In v2, the old options will be removed.
## 📈 Growth
A major release is always a good time to take a step back and reflect on whats been happening in terms of growth
and the greater community. The ecosystem surrounding MDX has already grown larger than we ever dreamed.Weve also
seen projects/products/application we never even imagined.
A major release is always a good time to take a step back and reflect on whats
been happening in terms of growth and the greater community.
The ecosystem surrounding MDX has already grown larger than we ever dreamed.
Weve also seen projects/products/application we never even imagined.
### Numbers
- **Downloads**: 125,000/week, 2.4M total
- **Stars**: 6,200
- **Contributors**: 50
- **Pull requests**: 281
- **Commits**: 670
* **Downloads**: 125,000/week, 2.4M total
* **Stars**: 6,200
* **Contributors**: 50
* **Pull requests**: 281
* **Commits**: 670
The contributor growth is one of the most important aspects here as we have numerous community members that are familiar
with MDX internals. This allows us to continually improve the project and spread the workload against an ever growing
team of contributors.
The contributor growth is one of the most important aspects here as we have
numerous community members that are familiar with MDX internals.
This allows us to continually improve the project and spread the workload
against an ever growing team of contributors.
[See the contributor graph](https://github.com/mdx-js/mdx/graphs/contributors)
### Ecosystem
- [Prettier](https://prettier.io)
- [Docz](https://docz.site)
- [MDX Deck](https://github.com/jxnblk/mdx-deck)
- [Next.js](https://nextjs.org)
- [Gatsby](https://gatsbyjs.org)
- [AST Explorer](https://astexplorer.net)
- [Vue support (alpha)](/vue)
- [Demoboard](https://frontarm.com/demoboard/)
- [Editors](/editors)
* [Prettier](https://prettier.io)
* [Docz](https://docz.site)
* [MDX Deck](https://github.com/jxnblk/mdx-deck)
* [Next.js](https://nextjs.org)
* [Gatsby](https://gatsbyjs.org)
* [AST Explorer](https://astexplorer.net)
* [Vue support (alpha)](/vue)
* [Demoboard](https://frontarm.com/demoboard/)
* [Editors](/editors)
## 🛣 Roadmap
With v1 released we have a roadmap in place that well continue working towards over the next 6 months or
so in addition to bug fixes and parsing issues we might encounter.
With v1 released we have a roadmap in place that well continue working towards
over the next 6 months or so in addition to bug fixes and parsing issues we
might encounter.
- MDXs: [#454](https://github.com/mdx-js/mdx/issues/454)
- Interleaving: [#195](https://github.com/mdx-js/mdx/issues/195)
- Global shortcodes: [#508](https://github.com/mdx-js/mdx/pull/508)
- Stable Vue support: [#238](https://github.com/mdx-js/mdx/issues/238)
- Blocks: MDX WYSIWYG: [blocks/blocks](https://github.com/blocks/blocks)
- MDX playground inspired by AST Explorer: [#220](https://github.com/mdx-js/mdx/issues/220)
- New splash page: [#444](https://github.com/mdx-js/mdx/issues/444)
- Showcase page: [#414](https://github.com/mdx-js/mdx/issues/414)
* MDXs: [#454](https://github.com/mdx-js/mdx/issues/454)
* Interleaving: [#195](https://github.com/mdx-js/mdx/issues/195)
* Global shortcodes: [#508](https://github.com/mdx-js/mdx/pull/508)
* Stable Vue support: [#238](https://github.com/mdx-js/mdx/issues/238)
* Blocks: MDX WYSIWYG: [blocks/blocks](https://github.com/blocks/blocks)
* MDX playground inspired by AST Explorer: [#220](https://github.com/mdx-js/mdx/issues/220)
* New splash page: [#444](https://github.com/mdx-js/mdx/issues/444)
* Showcase page: [#414](https://github.com/mdx-js/mdx/issues/414)
### Vue support
Supporting Vue is an important goal for MDX and is one of the primary reasons weve rearchitected MDX to use
custom pragma. Were delighted that **we now have an alpha version for Vue working**. Wed love it if anyone
from the Vue community wants to give it a try and provide feedback.
Supporting Vue is an important goal for MDX and is one of the primary reasons
weve rearchitected MDX to use custom pragma.
Were delighted that **we now have an alpha version for Vue working**.
Wed love it if anyone from the Vue community wants to give it a try and provide
feedback.
[See the Vue example](https://github.com/mdx-js/mdx/tree/master/examples/vue)
### Blocks project
One of the key missing aspects of authoring MDX documents is the editing experience. Currently, there isnt an
approachable way to write MDX unless you enjoy working in a text editor and writing raw Markdown/code. Wed
like to solve that and have begun work on an MDX “blocks editor” thats a **content-focused WYSIWYG**. Not to mention,
well be doing all that we can to make sure the editor is as accessible as it can be from the beginning.
One of the key missing aspects of authoring MDX documents is the editing
experience.
Currently, there isnt an approachable way to write MDX unless you enjoy working
in a text editor and writing raw Markdown/code.
Wed like to solve that and have begun work on an MDX “blocks editor” thats a
**content-focused WYSIWYG**.
Not to mention, well be doing all that we can to make sure the editor is as
accessible as it can be from the beginning.
When we have a beta ready we will be open sourcing it and announcing, so stay tuned.
When we have a beta ready we will be open sourcing it and announcing, so stay
tuned.
[Check out the Blocks project](https://github.com/blocks/blocks)
## unified collective
MDX is part of the unified collective, which is an open source ecosystem for dealing with many sources of content. unified
projects are used all over the web, and it would never be possible without financial support from our fine sponsors.
MDX is part of the unified collective, which is an open source ecosystem for
dealing with many sources of content.
unified projects are used all over the web, and it would never be possible
without financial support from our fine sponsors.
- [ZEIT](https://zeit.co) 🥇
- [Gatsby](https://gatsbyjs.org) 🥇
- [Holloway](https://www.holloway.com) 🥉
- [Backers](https://opencollective.com/unified#budget) 🏆
- [You?](https://opencollective.com/unified)👤
* [ZEIT](https://zeit.co) 🥇
* [Gatsby](https://gatsbyjs.org) 🥇
* [Holloway](https://www.holloway.com) 🥉
* [Backers](https://opencollective.com/unified#budget) 🏆
* [You?](https://opencollective.com/unified)👤
## 🙏 Thanks
Wed like to say thanks to all our contributors and our happy users. Special thanks to
Wed like to say thanks to all our contributors and our happy users.
Special thanks to
[@wooorm](https://github.com/wooorm),
[@silvenon](https://github.com/silvenon),
[@timneutkens](https://github.com/timneutkens),
@ -191,8 +226,8 @@ Wed like to say thanks to all our contributors and our happy users. Special t
[@sw-yx](https://github.com/sw-yx),
and anyone we may have forgotten.
---
***
Written by [John Otander](https://johno.com)
**[&lt; Back to blog](/blog)**
**[\< Back to blog](/blog)**

View File

@ -15,6 +15,22 @@ free customer service.
## Contents
* [Support](#support)
* [Contributions](#contributions)
* [Financial support](#financial-support)
* [Improve documentation](#improve-documentation)
* [Improve issues](#improve-issues)
* [Give feedback on issues and pull requests](#give-feedback-on-issues-and-pull-requests)
* [Write code](#write-code)
* [Running the tests](#running-the-tests)
* [Running the docs site](#running-the-docs-site)
* [Submitting an issue](#submitting-an-issue)
* [Submitting a pull request](#submitting-a-pull-request)
* [Project structure](#project-structure)
* [Releases](#releases)
* [Troubleshooting](#troubleshooting)
* [Resources](#resources)
## Support
[Read the Support guidelines on the MDX website][support].
@ -53,9 +69,10 @@ Were always looking for more opinions on discussions in the issue tracker.
### Write code
Code contributions are very welcome. Its often good to first create an issue
to report a bug or suggest a new feature before creating a pull request to
prevent you from doing unnecessary work.
Code contributions are very welcome.
Its often good to first create an issue to report a bug or suggest a new
feature before creating a pull request to prevent you from doing unnecessary
work.
## Running the tests
@ -63,8 +80,9 @@ prevent you from doing unnecessary work.
2. `yarn test`
Tests for an individual package can be run as a yarn workspace:
`yarn workspace remark-mdx test`. To see what packages are available to test
you can list out all workspaces with `yarn workspaces info`.
`yarn workspace remark-mdx test`.
To see what packages are available to test you can list out all workspaces with
`yarn workspaces info`.
## Running the docs site
@ -74,44 +92,45 @@ you can list out all workspaces with `yarn workspaces info`.
## Submitting an issue
- The issue tracker is for issues. Use chat for support
- Search the issue tracker (including closed issues) before opening a new
* The issue tracker is for issues.
Use chat for support
* Search the issue tracker (including closed issues) before opening a new
issue
- Ensure youre using the latest version of our packages
- Use a clear and descriptive title
- Include as much information as possible: steps to reproduce the issue,
* Ensure youre using the latest version of our packages
* Use a clear and descriptive title
* Include as much information as possible: steps to reproduce the issue,
error message, version, operating system, etcetera
- The more time you put into an issue, the better we will be able to help you
- The best issue report is a [failing test][unit-test] proving it
* The more time you put into an issue, the better we will be able to help you
* The best issue report is a [failing test][unit-test] proving it
## Submitting a pull request
- Non-trivial changes are often best discussed in an issue first, to prevent
* Non-trivial changes are often best discussed in an issue first, to prevent
you from doing unnecessary work
- For ambitious tasks, you should try to get your work in front of the
* For ambitious tasks, you should try to get your work in front of the
community for feedback as soon as possible
- New features should be accompanied with tests and documentation
- Dont include unrelated changes
- Test before submitting code by running `yarn test`
- Write a convincing description of why we should land your pull request:
* New features should be accompanied with tests and documentation
* Dont include unrelated changes
* Test before submitting code by running `yarn test`
* Write a convincing description of why we should land your pull request:
its your job to convince us
## Project structure
MDX is a monorepo that uses [lerna][].
- All packages are found in `./packages`
- All documentation is found in `./docs` and can be viewed with `yarn docs -- -o`
- Theres an `./examples` directory where examples for different tools and
* All packages are found in `./packages`
* All documentation is found in `./docs` and can be viewed with `yarn docs -- -o`
* Theres an `./examples` directory where examples for different tools and
frameworks
## Releases
In order to release a new version you can follow these steps:
- Draft a release for the next version (vX.X.X)
- `yarn && yarn test && yarn lerna publish --force-publish`
- Publish release on GitHub
* Draft a release for the next version (vX.X.X)
* `yarn && yarn test && yarn lerna publish --force-publish`
* Publish release on GitHub
## Troubleshooting
@ -121,16 +140,22 @@ If youre having issues installing locally you might need to run
## Resources
- [Good first issues in the MDX repository](https://github.com/mdx-js/mdx/labels/good%20first%20issue%20👋)
- [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/)
- [Making your first contribution](https://medium.com/@vadimdemedes/making-your-first-contribution-de6576ddb190)
- [Using Pull Requests](https://help.github.com/articles/about-pull-requests/)
- [GitHub Help](https://help.github.com)
* [Good first issues in the MDX repository](https://github.com/mdx-js/mdx/labels/good%20first%20issue%20👋)
* [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/)
* [Making your first contribution](https://medium.com/@vadimdemedes/making-your-first-contribution-de6576ddb190)
* [Using Pull Requests](https://help.github.com/articles/about-pull-requests/)
* [GitHub Help](https://help.github.com)
[coc]: https://github.com/mdx-js/.github/blob/master/code-of-conduct.md
[support]: https://mdxjs.com/support
[unit-test]: https://twitter.com/sindresorhus/status/579306280495357953
[collective]: https://opencollective.com/unified
[micromark]: https://github.com/micromark/micromark
[lerna]: https://lerna.js.org
[lerna-install]: https://github.com/lerna/lerna/issues/1457

View File

@ -2,23 +2,27 @@
The community has begun adding MDX syntax highlighting support for some editors!
- [vscode][]: VSCode
- [vscode-mdx-preview][]: MDX Preview for VS Code
- [vim][]: Vim
- [sublime][]: Sublime
- [JetBrains IntelliJ/WebStorm][jetbrains]
* [vscode][]: VSCode
* [vscode-mdx-preview][]: MDX Preview for VS Code
* [vim][]: Vim
* [sublime][]: Sublime
* [JetBrains IntelliJ/WebStorm][jetbrains]
### Editors needing support
- Atom
- Emacs
* Atom
* Emacs
---
***
Original GitHub issue: [#119](https://github.com/mdx-js/mdx/issues/119)
[vscode]: https://github.com/silvenon/vscode-mdx
[vscode-mdx-preview]: https://github.com/xyc/vscode-mdx-preview
[vim]: https://github.com/jxnblk/vim-mdx-js
[sublime]: https://github.com/jonsuh/mdx-sublime
[jetbrains]: https://plugins.jetbrains.com/plugin/14944-mdx

View File

@ -85,7 +85,8 @@ yarn add babel-loader@$VERSION --dev
(where `$VERSION` is the version number printed in the error message, such as
`8.1.0`).
Then, running `yarn start` again should do the trick! ✨
Then, running `yarn start` again should do the trick!
If youre still seeing errors and youre using TypeScript, then [this
guide][typescript] might help.
@ -93,7 +94,11 @@ guide][typescript] might help.
Finally, see [Support][] if youre still running into problems.
[cra]: https://github.com/facebook/create-react-app
[loader]: https://github.com/mdx-js/mdx/tree/main/packages/loader
[babel-loader]: https://webpack.js.org/loaders/babel-loader/
[typescript]: https://mdxjs.com/advanced/typescript
[support]: https://mdxjs.com/support

View File

@ -11,7 +11,8 @@ cd gatsby-site
yarn add gatsby-plugin-mdx @mdx-js/mdx@latest @mdx-js/react@latest
```
Then add `gatsby-plugin-mdx` to your `gatsby-config.js` in the `plugins` section.
Then add `gatsby-plugin-mdx` to your `gatsby-config.js` in the `plugins`
section.
```javascript
module.exports = {
@ -35,5 +36,7 @@ For more documentation on programmatically creating pages with Gatsby, see
the [Gatsby MDX docs][gatsby-mdx-docs].
[gatsby]: https://gatsbyjs.com
[gatsby-mdx-docs]: https://gatsbyjs.com/docs/mdx/
[gatsby-plugin-mdx]: https://gatsbyjs.com/packages/gatsby-plugin-mdx/

View File

@ -10,11 +10,13 @@ the installation guides.
{
(() => {
const advanced = props.navTree.children.find((item) => item.name === '/getting-started/')
const category = props.navTree.children.find(
item => item.name === '/getting-started/'
)
return (
<nav>
<NavGroup items={advanced.children} includeDescription />
<NavGroup items={category.children} includeDescription />
</nav>
)
})()
@ -22,6 +24,18 @@ the installation guides.
## Contents
* [Hello World](#hello-world)
* [Syntax](#syntax)
* [Markdown](#markdown)
* [JSX](#jsx)
* [MDX](#mdx)
* [Working with components](#working-with-components)
* [MDXProvider](#mdxprovider)
* [Table of components](#table-of-components)
* [Installation guides](#installation-guides)
* [Scaffold out an app](#scaffold-out-an-app)
* [Do it yourself](#do-it-yourself)
## Hello World
The smallest MDX example looks like this:
@ -100,15 +114,13 @@ with the benefits of JSX.
The following example shows how they can be combined.
Its interactive so go ahead and change the code!
<Editor
children={`Hello, *world*!
<Editor children={`Hello, *world*!
Below is an example of JSX embedded in Markdown.\\
<div style={{padding: '20px', backgroundColor: 'tomato', color: 'black' }}>
**Try and change the background color!**
</div>`}
/>
</div>`}/>
MDX supports two more features: [imports][] and [exports][].
@ -173,7 +185,8 @@ import Contributing from './docs/contributing.mdx'
[`export` (ES2015)][export] can be used to export data and components.
For example, you can export metadata like which layout to use or the authors of
a document.
Its a mechanism for an imported MDX file to communicate with the thing that imports it.
Its a mechanism for an imported MDX file to communicate with the thing that
imports it.
Say we import our MDX file, using webpack and React, like so:
@ -224,8 +237,9 @@ structures.
##### Defining variables with exports
If you need to define a variable in your MDX document, you can use an export
to do so. Not only do exports emit data, they instantiate data you can reference
in JSX blocks:
to do so.
Not only do exports emit data, they instantiate data you can reference in JSX
blocks:
```js
export const myVariable = 'Yay!'
@ -350,7 +364,7 @@ Sometimes from an MDX file you might want to override the wrapper.
This is especially useful when you want to override layout for a single entry
point at the page level.
To achieve this you can use the ES default [export][] and it will wrap your MDX
document _instead_ of the wrapper passed to MDXProvider.
document *instead* of the wrapper passed to MDXProvider.
You can declare a default export as a function:
@ -393,11 +407,11 @@ Now that weve gone over how MDX works, youre ready to get installing.
If youre the type of person that wants to scaffold out an app quickly and start
playing around you can use `npm init`:
- `npm init mdx` [`webpack`](/getting-started/webpack)
- `npm init mdx` [`parcel`](/getting-started/parcel)
- `npm init mdx` [`next`](/getting-started/next)
- `npm init mdx` [`gatsby`](/getting-started/gatsby)
- `npm init mdx` [`react-static`](/getting-started/react-static)
* `npm init mdx` [`webpack`](/getting-started/webpack)
* `npm init mdx` [`parcel`](/getting-started/parcel)
* `npm init mdx` [`next`](/getting-started/next)
* `npm init mdx` [`gatsby`](/getting-started/gatsby)
* `npm init mdx` [`react-static`](/getting-started/react-static)
### Do it yourself
@ -448,12 +462,21 @@ const renderWithReact = async mdxCode => {
```
[imports]: #imports
[exports]: #exports
[components]: #table-of-components
[md]: https://daringfireball.net/projects/markdown/syntax
[jsx]: https://reactjs.org/docs/introducing-jsx.html
[import]: https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/import
[export]: https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/export
[rebass]: https://rebassjs.org
[transclude]: https://en.wikipedia.org/wiki/Transclusion
[context]: https://reactjs.org/docs/context.html

View File

@ -10,11 +10,13 @@ import {Note} from '../_component/note.server.js'
npm install --save-dev parcel react react-dom
```
- `parcel` in order to `npm exec -- parcel`.
- `react` so Parcel [detects][isjsx] that the `@parcel/transformer-mdx` output is JSX.
* `parcel` in order to `npm exec -- parcel`.
* `react` so Parcel [detects][isjsx] that the `@parcel/transformer-mdx` output
is JSX.
This seems unnecessary, but actually it is.
Probably in the future the MDX transformer will [compile away the JSX][xdm jsx] -- but [not in every case][xdm vue]?
- `react-dom` to render the output into the DOM.
Probably in the future the MDX transformer will
[compile away the JSX][xdm jsx] -- but [not in every case][xdm vue]?
* `react-dom` to render the output into the DOM.
## Use
@ -24,9 +26,13 @@ npm exec -- parcel index.html
## Guide
To get started, see the [MDX + Parcel example][example], the Parcel [web app][web app recipe] and Parcel [React][react recipe] recipes and the [@mdx-js/react][] package.
To get started, see the [MDX + Parcel example][example], the Parcel
[web app][web app recipe] and Parcel [React][react recipe] recipes and the
[@mdx-js/react][] package.
Synthesizing those resources, assume your project contains the following three files: `index.html`, `hello.js` and `hello.mdx`, and that `hello.js` contains the following React:
Synthesizing those resources, assume your project contains the following three
files: `index.html`, `hello.js` and `hello.mdx`, and that `hello.js` contains
the following React:
```javascript
// hello.js
@ -48,7 +54,8 @@ ReactDOM.render(
)
```
Running `npm exec -- parcel index.html` will build it, and visiting http://localhost:1234 will contain:
Running `npm exec -- parcel index.html` will build it, and visiting
[http://localhost:1234](http://localhost:1234) will contain:
```html
<h1 style="color:tomato">Hello, World! 2</h1>
@ -61,22 +68,32 @@ Running `npm exec -- parcel index.html` will build it, and visiting http://local
```
{/* eslint-disable react/no-unescaped-entities */}
{/* https://github.com/mdx-js/mdx/pull/1626#discussion_r701205052 */}
<Note>
[You need to use][type=module]
`<script src="hello.js" type="module"></script>` to reference `hello.js`
from `index.html`, otherwise you will see the following error:
[You need to use][type=module] `<script src="hello.js" type="module"></script>` to reference `hello.js` from `index.html`, otherwise you will see the following error:
> @parcel/transformer-js: Browser scripts cannot have imports or exports.
> [**@parcel/transformer-js**](https://github.com/parcel/transformer-js):
> Browser scripts cannot have imports or exports.
</Note>
[@mdx-js/react]: https://www.npmjs.com/package/@mdx-js/react
[@parcel/transformer-mdx]: https://www.npmjs.com/package/@parcel/transformer-mdx
[example]: https://github.com/mdx-js/mdx/tree/main/examples/parcel
[isjsx]: https://github.com/parcel-bundler/parcel/blob/f03eddda4ca3de324586a163e3341ae88a8729d8/packages/transformers/js/src/JSTransformer.js#L225-L229
[react recipe]: https://v2.parceljs.org/recipes/react
[type=module]: https://v2.parceljs.org/languages/javascript/#:~:text=Parcel%20matches,one%20below.
[web app recipe]: https://v2.parceljs.org/getting-started/webapp
[xdm jsx]: https://github.com/wooorm/xdm#optionsjsx
[xdm vue]: https://github.com/wooorm/xdm#vue

View File

@ -1,5 +1,3 @@
import BabelConfiguration from '../_component/babel-configuration.server.mdx'
# Webpack
MDX provides a built in webpack loader you need to install and configure
@ -13,8 +11,8 @@ npm install --save-dev @mdx-js/loader
## Configuration
The loader needs to be used in tandem with the [babel-loader][]. Most projects will typically
already include this if you are using JSX syntax.
The loader needs to be used in tandem with the [babel-loader][].
Most projects will typically already include this if you are using JSX syntax.
For webpack projects you can define the following `webpack.config.js` extension
handler for `.md` and `.mdx` files:
@ -36,12 +34,13 @@ module.exports = {
}
```
If you only want the loader for `.mdx` files you can change the regex to `/\.mdx$/`.
If you only want the loader for `.mdx` files you can change the regex to
`/\.mdx$/`.
The transpiled output for MDX requires [babel][] to be run. This is typically
by adding in the babel-loader to run _after_ the MDX loader. Webpack starts
from the end of the loaders array and works backward, so it is important to
follow the ordering above.
The transpiled output for MDX requires [babel][] to be run.
This is typically by adding in the babel-loader to run *after* the MDX loader.
Webpack starts from the end of the loaders array and works backward, so it is
important to follow the ordering above.
## Using plugins
@ -75,8 +74,8 @@ module.exports = {
## Running MDX in the browser
If youre running MDX in the browser you will need to configure webpack to ignore
the `fs` module:
If youre running MDX in the browser you will need to configure webpack to
ignore the `fs` module:
```js
module.exports = {
@ -86,9 +85,28 @@ module.exports = {
}
```
[See the webpack docs](https://webpack.js.org/configuration/node/#other-node-core-libraries)
[See the webpack
docs](https://webpack.js.org/configuration/node/#other-node-core-libraries)
<BabelConfiguration />
## Babel configuration
You will also need to configure [babel][] to support the language features that
MDX uses.
One way you can achieve that is using the following `.babelrc` at your project
root.
```json
{
"presets": ["@babel/env", "@babel/react"]
}
```
And installing the dependencies:
```sh
npm install --save-dev @babel/preset-env @babel/preset-react
```
[babel-loader]: https://webpack.js.org/loaders/babel-loader/
[babel]: https://babeljs.io

View File

@ -8,8 +8,8 @@ import {Note} from '../_component/note.server.js'
Proceed with caution!
</Note>
[x0][] is a zero-config tool with built in support for MDX. You will need
to install the library and set up the npm script.
[x0][] is a zero-config tool with built in support for MDX.
You will need to install the library and set up the npm script.
## Installation
@ -29,8 +29,9 @@ Then, in your `package.json` add the following to the `scripts`:
## Customizing the layout
[x0][] supports MDX files with either `.md` or `.mdx` file extensions out of
the box. For components requiring providers you will need to use customize
`_app.js`. Heres an example using [Rebass][] components:
the box.
For components requiring providers you will need to use customize `_app.js`.
Heres an example using [Rebass][] components:
```jsx
import React from 'react'
@ -48,4 +49,5 @@ export default ({route, routes, ...props}) => (
```
[x0]: https://compositor.io/x0
[rebass]: https://rebassjs.com

View File

@ -9,8 +9,9 @@ import {Note} from '../_component/note.server.js'
</Note>
[Zero](https://zeroserver.io) is a no-config web framework for React, MDX,
Node.js, and Vue. It has built in support for MDX. To get started, install
Zero (globally or locally in your project).
Node.js, and Vue.
It has built in support for MDX.
To get started, install Zero (globally or locally in your project).
## Installation
@ -35,7 +36,7 @@ Zero has some additional features for MDX, you can [read them here](https://gith
## Resources
- [Example Project](https://github.com/mdx-js/mdx/tree/9d5d000d749de0294cc3577f3c9b4db372dbc296/examples/zero)
- [Zero GitHub](https://github.com/remoteinterview/zero/)
- [Zero Website](https://zeroserver.io/)
- [Zero MDX Docs](https://github.com/remoteinterview/zero/tree/master/docs/mdx)
* [Example Project](https://github.com/mdx-js/mdx/tree/9d5d000d749de0294cc3577f3c9b4db372dbc296/examples/zero)
* [Zero GitHub](https://github.com/remoteinterview/zero/)
* [Zero Website](https://zeroserver.io/)
* [Zero MDX Docs](https://github.com/remoteinterview/zero/tree/master/docs/mdx)

View File

@ -1,8 +1,14 @@
# Custom loader
By design, the default MDX is very minimal and likely wont see any additional features outside of the MDX spec. However, webpack [makes it straightforward][webpack-loader] to write your own loader to add custom syntax support.
By design, the default MDX is very minimal and likely wont see any additional
features outside of the MDX spec.
However, webpack [makes it straightforward][webpack-loader] to write your own
loader to add custom syntax support.
Consider a scenario where you wanted to add frontmatter support to all your MDX documents. You could achieve this with a remark plugin or a custom loader. Here well write a custom loader:
Consider a scenario where you wanted to add frontmatter support to all your MDX
documents.
You could achieve this with a remark plugin or a custom loader.
Here well write a custom loader:
```js
// lib/fm-loader.js
@ -21,7 +27,9 @@ ${content}`
}
```
The loader code above parses out the frontmatter, exports it as the named export `frontMatter`, and then returns the rest of the document which will then be handled by `@mdx-js/loader` and then `babel-loader`.
The loader code above parses out the frontmatter, exports it as the named
export `frontMatter`, and then returns the rest of the document which will then
be handled by `@mdx-js/loader` and then `babel-loader`.
Then, you can use it with the following config:

View File

@ -10,11 +10,13 @@ to add to them by [contributing](/contributing)!
{
(() => {
const advanced = props.navTree.children.find((item) => item.name === '/guides/')
const category = props.navTree.children.find(
item => item.name === '/guides/'
)
return (
<nav>
<NavGroup items={advanced.children} includeDescription />
<NavGroup items={category.children} includeDescription />
</nav>
)
})()

View File

@ -5,8 +5,9 @@ If you havent read the syntax highlighting guide its recommended start the
# Live code editor
An increasingly common approach for live code editors is to overload the
code block. This is often done so that the code shows up nicely when rendered
to GitHub and its a nice usage of meta strings.
code block.
This is often done so that the code shows up nicely when rendered to GitHub and
its a nice usage of meta strings.
## Code block meta string
@ -89,8 +90,8 @@ export default props => (
## Using the MDXProvider context for rendering
With the react-live editor you can ensure that your MDX components
in context are rendered in the preview. In order to do this you
can use the MDX custom pragma.
in context are rendered in the preview.
In order to do this you can use the MDX custom pragma.
To achieve this, import the pragma:

View File

@ -2,11 +2,13 @@ export const navExclude = true
# Markdown in components
One great feature about MDX is that you can use Markdown within your JSX components.
One great feature about MDX is that you can use Markdown within your JSX
components.
## Example
Lets say you wanted to create a custom `<Note />` component. You could do something like this.
Lets say you wanted to create a custom `<Note />` component.
You could do something like this.
Using MDX 2:
@ -23,7 +25,8 @@ Here is my `<Note />` component.
</Note>
```
The same example, using MDX 1 (notice the need blank lines between the tags and the content):
The same example, using MDX 1 (notice the need blank lines between the tags and
the content):
```mdx
import Note from './Note'

View File

@ -1,6 +1,11 @@
# Math blocks
You can render math blocks via [remark-math](https://github.com/remarkjs/remark-math/tree/main/packages/remark-math) and [rehype-katex](https://github.com/remarkjs/remark-math/tree/main/packages/rehype-katex). remark-math parses math blocks and rehype-katex transforms the blocks into html elements with classes for styling. Also, you need to apply css style of [KaTeX](https://katex.org/) by yourself to render them properly.
You can render math blocks via [remark-math](https://github.com/remarkjs/remark-math/tree/main/packages/remark-math)
and [rehype-katex](https://github.com/remarkjs/remark-math/tree/main/packages/rehype-katex).
remark-math parses math blocks and rehype-katex transforms the blocks into html
elements with classes for styling.
Also, you need to apply css style of [KaTeX](https://katex.org/) by yourself to
render them properly.
First, link a stylesheet and use the `$` syntax:
@ -67,7 +72,8 @@ module.exports = {
}
```
If youre using MDX with Next.js, you can use `@next/mdx` with the following configuration:
If youre using MDX with Next.js, you can use `@next/mdx` with the following
configuration:
```js
// next.config.js

View File

@ -1,6 +1,9 @@
# MDX Embed
With [MDX Embed](https://www.mdx-embed.com/) you can [politely embed](https://www.gatsbyjs.com/blog/hacktoberfest-spotlight-mdx-embed/) and load 3rd party media content such as Twitter, CodePen, CodeSandbox, Egghead Lessons, Gists and many more in your `.mdx`, no **import** required!
With [MDX Embed](https://www.mdx-embed.com/) you can
[politely embed](https://www.gatsbyjs.com/blog/hacktoberfest-spotlight-mdx-embed/)
and load 3rd party media content such as Twitter, CodePen, CodeSandbox, Egghead
Lessons, Gists and many more in your `.mdx`, no **import** required!
## Install
@ -10,7 +13,8 @@ npm install mdx-embed --save
## Setup
Wrap your application with the `MDXEmbedProvider` to allow your `.mdx` to render all of the provided components
Wrap your application with the `MDXEmbedProvider` to allow your `.mdx` to render
all of the provided components
```javascript
import React from 'react'
@ -31,4 +35,5 @@ Here's a pen, and some other blog post text
<CodePen codePenId="PNaGbb" />
```
For the full installation and information about the various MDX packages visit the [docs](https://www.mdx-embed.com)
For the full installation and information about the various MDX packages visit
the [docs](https://www.mdx-embed.com)

View File

@ -2,8 +2,8 @@
There are two primary approaches for adding syntax highlighting to MDX:
- composition via the MDXProvider
- remark plugin
* composition via the MDXProvider
* remark plugin
Its typically preferred to take the compositional approach, but both
will be documented here.
@ -11,9 +11,9 @@ will be documented here.
## Composition
The [MDXProvider](https://mdxjs.com/getting-started/#mdxprovider) provides
a way to map components to be rendered for a given Markdown element. So,
this allows you to choose a specific component for the `code` block. To
get started you can wrap your app in the MDXProvider and add in a component
a way to map components to be rendered for a given Markdown element.
So, this allows you to choose a specific component for the `code` block.
To get started you can wrap your app in the MDXProvider and add in a component
to ensure its being picked up:
### Using the MDXProvider
@ -41,8 +41,9 @@ any code block found in your MDX files.
### prism-react-renderer
Now that you have a custom component being rendered for code blocks you can
choose any React component library to handle the syntax highlighting. A solid
library to choose is [prism-react-renderer](https://github.com/FormidableLabs/prism-react-renderer).
choose any React component library to handle the syntax highlighting.
A solid library to choose is
[prism-react-renderer](https://github.com/FormidableLabs/prism-react-renderer).
You can install it with:
@ -53,9 +54,10 @@ yarn add prism-react-renderer
#### Build a CodeBlock component
You can essentially cut and paste the entire example into a new
component file. The only big difference is the MDX will pass in the
code string as `children` so you will need to destructure that prop
and pass it to Highlight as the `code` prop.
component file.
The only big difference is the MDX will pass in the code string as `children` so
you will need to destructure that prop and pass it to Highlight as the `code`
prop.
```js
// src/CodeBlock.js
@ -81,10 +83,11 @@ export default ({children}) => {
}
```
Now you should see syntax highlighting in your MDX files. However, right now
`javascript` is hardcoded as the language. You will need to take the language
from the code fence and pass it to Highlight directly. MDX will pass the language
as `className` so you can pull out the language with:
Now you should see syntax highlighting in your MDX files.
However, right now `javascript` is hardcoded as the language.
You will need to take the language from the code fence and pass it to Highlight
directly.
MDX will pass the language as `className` so you can pull out the language with:
```js
const language = className.replace(/language-/, '')
@ -122,7 +125,8 @@ export default ({children, className}) => {
## Remark plugin
In addition to composition you can use any plugin from the remark
ecosystem. One solid library for syntax highlighting is
ecosystem.
One solid library for syntax highlighting is
[@mapbox/rehype-prism](https://github.com/mapbox/rehype-prism).
```js

View File

@ -112,9 +112,10 @@ render(
)
```
See the result: https://twitter.com/4lpine/status/1141781114786160641.
See the result: [https://twitter.com/4lpine/status/1141781114786160641](https://twitter.com/4lpine/status/1141781114786160641).
[See the full example](https://github.com/mdx-js/mdx/tree/master/examples/terminal)
[ink]: https://github.com/vadimdemedes/ink
[runtime]: https://mdxjs.com/advanced/runtime

View File

@ -39,5 +39,6 @@ module.exports = {
}
```
Thats it. Now restart your server and you should be able to create `.mdx` files
and import them in other components.
Thats it.
Now restart your server and you should be able to create `.mdx` files and import
them in other components.

View File

@ -3,23 +3,25 @@ import {Note} from '../_component/note.server.js'
# Wrapper customization
The [wrapper](/getting-started#using-the-wrapper) component can be used
to set the layout for the MDX document. Its often used to set container
width, borders, background colors, etc. However, its also unique because
it has access to the children passed to it.
to set the layout for the MDX document.
Its often used to set container width, borders, background colors, etc.
However, its also unique because it has access to the children passed to it.
This means that you can do powerful things with the MDX document elements.
If you arent very familiar with React children, it might be worthwhile to
start with [_A deep dive into children in React_](https://mxstbr.blog/2017/02/react-children-deepdive/)
start with
[*A deep dive into children in React*](https://mxstbr.blog/2017/02/react-children-deepdive/)
by Max Stoiber.
> We can render arbitrary components as children, but still control them from the
> parent instead of the component we render them from.
> We can render arbitrary components as children, but still control them from
> the parent instead of the component we render them from.
>
> _Max Stoiber - A deep dive into children in React_
> *Max Stoiber - A deep dive into children in React*
The implications of this are very interesting from the context of an
MDX wrapper component. This means the wrapper can do things like reordering
components, wrapping them, or even further customizing them.
The implications of this are very interesting from the context of an MDX wrapper
component.
This means the wrapper can do things like reordering components, wrapping them,
or even further customizing them.
## Getting started
@ -66,11 +68,11 @@ export default props => (
(`>=1.0.0-alpha.7`)
</Note>
Sometimes you might want to inspect the element type of that
MDX will be rendering with its custom pragma. You can use the
wrapper to achieve this because it will have access to the MDX
components as children. You can check their type by accessing
the `mdxType` in props.
Sometimes you might want to inspect the element type of that MDX will be
rendering with its custom pragma.
You can use the wrapper to achieve this because it will have access to the MDX
components as children.
You can check their type by accessing the `mdxType` in props.
```js
// src/App.js
@ -94,8 +96,9 @@ export default props => (
### Manipulating children
You can also manipulate and modify children. Here is an example of reordering
them by converting them to an array and calling `reverse`.
You can also manipulate and modify children.
Here is an example of reordering them by converting them to an array and calling
`reverse`.
```js
// src/App.js
@ -120,10 +123,10 @@ export default props => (
## Related
If you would like to dive deeper, check out
[_A deep dive into children in React_](https://mxstbr.blog/2017/02/react-children-deepdive/)
[*A deep dive into children in React*](https://mxstbr.blog/2017/02/react-children-deepdive/)
or Brent Jacksons [MDX Blocks](https://github.com/jxnblk/mdx-blocks)
---
***
- [React children deep dive](https://mxstbr.blog/2017/02/react-children-deepdive)
- [MDX Blocks](https://github.com/jxnblk/mdx-blocks)
* [React children deep dive](https://mxstbr.blog/2017/02/react-children-deepdive)
* [MDX Blocks](https://github.com/jxnblk/mdx-blocks)

View File

@ -2,15 +2,20 @@ import {Note} from '../_component/note.server.js'
# Writing a plugin
For a full-fledged introduction to plugins its recommended to read the [remark guides][remark-guides] and study up on [syntax trees][syntax-trees].
For a full-fledged introduction to plugins its recommended to read the
[remark guides][remark-guides] and study up on [syntax trees][syntax-trees].
Now lets consider an example where you want to pass all headings through the [title][] module to ensure consistent capitalization. We can use [unist-util-visit][] to visit all headings and change the text nodes with `title(text)`.
Now lets consider an example where you want to pass all headings through the
[title][] module to ensure consistent capitalization.
We can use [unist-util-visit][] to visit all headings and change the text nodes
with `title(text)`.
## Visiting heading nodes
The first thing you want to do is install the `unist-util-visit` library. This is a utility library that allows you
to visit all heading (or any other type of nodes) without having to write a lot of boiler plate code. It handles that
for you.
The first thing you want to do is install the `unist-util-visit` library.
This is a utility library that allows you to visit all heading (or any other
type of nodes) without having to write a lot of boiler plate code.
It handles that for you.
Then you can first log out the nodes to see it in action:
@ -24,14 +29,15 @@ module.exports = () => (tree, file) => {
}
```
This will log out all the nodes in your document that are headings. Inside heading nodes there are text nodes. These
include the raw text included in the heading.
This will log out all the nodes in your document that are headings.
Inside heading nodes there are text nodes.
These include the raw text included in the heading.
<Note>
The reason that heading nodes include multiple text node types is because
there can be other “[phrasing content][phrasing]” nodes. For example if your
heading looked like `# Hello, _world_`. In addition to the text there is also
an emphasis node.
there can be other “[phrasing content][phrasing]” nodes.
For example if your heading looked like `# Hello, _world_`.
In addition to the text there is also an emphasis node.
</Note>
## Visiting text nodes
@ -52,8 +58,8 @@ module.exports = () => (tree, file) => {
## Using the title library
Now that you are logging out the text nodes, you can now manipulate them with the title library by reassigning the value
to the node:
Now that you are logging out the text nodes, you can now manipulate them with
the title library by reassigning the value to the node:
```js
const title = require('title')
@ -70,7 +76,11 @@ module.exports = () => (tree, file) => {
```
[remark-guides]: https://github.com/remarkjs/remark/blob/master/doc/plugins.md#creating-plugins
[syntax-trees]: https://github.com/syntax-tree/unist#syntax-tree
[title]: https://github.com/zeit/title
[unist-util-visit]: https://github.com/syntax-tree/unist-util-visit
[phrasing]: https://www.w3.org/TR/2011/WD-html5-author-20110809/content-models.html#phrasing-content-0

View File

@ -2,11 +2,18 @@ import {Chart} from './_component/snowfall.server.js'
export {Home as default} from './_component/home.server.js'
export const year = 2018
{/* lint disable heading-style */}
Markdown for the\
**component era**
=
=================
MDX is an authorable format that lets you seamlessly write JSX in your Markdown documents. You can import components, such as interactive charts or alerts, and embed them within your content. This makes writing long-form content with components a blast 🚀.
MDX is an authorable format that lets you seamlessly write JSX in your Markdown
documents.
You can import components, such as interactive charts or alerts, and embed them
within your content.
This makes writing long-form content with components a blast.
🚀
***
@ -33,14 +40,22 @@ MDX is an authorable format that lets you seamlessly write JSX in your Markdown
<div className="home-column-end">
Its compiled to JavaScript you can use in any framework that supports JSX:
{/* lint disable */}
<div className="home-preview">
# Last years snowfall
In {year}, the snowfall was above average. It was followed by a warm spring
which caused flood conditions in many of the nearby rivers.
In {year}, the snowfall was above average.
It was followed by a warm spring which caused flood conditions in many of
the nearby rivers.
<Chart year={year} color="#fcb32c" />
<Chart
year={year}
color="#fcb32c"
/>
</div>
{/* lint enable */}
</div>
</div>
@ -48,7 +63,14 @@ MDX is an authorable format that lets you seamlessly write JSX in your Markdown
## New: MDX v2!
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.
* Bullet
* Bullet

View File

@ -1,6 +1,13 @@
export const navExclude = true
Paragraph lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Paragraph lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.
# Markdown
@ -14,10 +21,19 @@ Paragraph lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusm
###### h6
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.
## Code
{/* lint disable fenced-code-flag */}
```
code w/o flag
```
@ -26,14 +42,29 @@ code w/o flag
console.log('js')
```
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.
## Thematic break
Thematic break:
---
***
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.
## HTML (MDX)
@ -41,40 +72,76 @@ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
HTML (or well, for us, MDX)
</div>
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.
## List
- List
- Items
* List
* Items
1. List
2. Items
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.
4. List
4. Items
1. * Item
5. Items
6. * Item
* Other Item
- More list
* More list
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.
## Block quote
> Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
> Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
> tempor incididunt ut labore et dolore magna aliqua.
> Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
> aliquip ex ea commodo consequat.
> Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
> eu fugiat nulla pariatur.
> Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
> deserunt mollit anim id est laborum.
>
> ```js
> console.log('code')
> ```
>
> - List item
> * List item
>
> > Another quote.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.
## Phrasing
@ -84,14 +151,20 @@ Some *emphasis*, **strong**, and ***both***.
A [link](https://example.com).
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.
## GFM
| |
| - |
| a | b | c | d |
| - | :- | -: | :-: |
| e | f | g | h |
@ -102,9 +175,16 @@ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
* [x] checked
* [ ] unchecked
~strikethrough~.
~~strikethrough~~.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.
## Other
@ -112,4 +192,11 @@ A keyboard: <kbd>cmd+f</kbd>.
A <button>button</button>.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.

View File

@ -6,21 +6,21 @@ export const navSortSelf = 1
## Markdown for the component era
MDX is an authorable format that lets you seamlessly write JSX in your Markdown
documents. You can import components, such as interactive charts or alerts, and
embed them within your content. This makes writing long-form content with
components a blast. 🚀
documents.
You can import components, such as interactive charts or alerts, and embed them
within your content.
This makes writing long-form content with components a blast.
🚀
## Try it
<Editor
children={`Hello, *world*!
<Editor children={`Hello, *world*!
Below is an example of JSX embedded in Markdown.
<div style={{padding: '20px', backgroundColor: 'tomato', color: 'black' }}>
**Try and change the background color!**
</div>`}
/>
</div>`}/>
## In short
@ -39,26 +39,30 @@ you interleave JSX only when you want to.
🔥 **Blazingly blazing fast**: MDX has no runtime, all compilation occurs
during the build stage.
> Its extremely useful for using design system components to render markdown
> and weaving interactive components in with existing markdown.
> Its extremely useful for using design system components to render markdown
> and weaving interactive components in with existing markdown.
>
> — [**@chrisbiscardi**][quote]
## Why?
Before MDX, some of the benefits of writing Markdown were lost when integrating
with JSX. Implementations were often template string-based which required lots
of escaping and cumbersome syntax.
with JSX.
Implementations were often template string-based which required lots of escaping
and cumbersome syntax.
MDX seeks to make writing with Markdown _and_ JSX simpler while being more
expressive. Writing is fun again when you combine components, that can
even be dynamic or load data, with the simplicity of Markdown for long-form
content.
MDX seeks to make writing with Markdown *and* JSX simpler while being more
expressive.
Writing is fun again when you combine components, that can even be dynamic or
load data, with the simplicity of Markdown for long-form content.
Watch @kentcdodds introduce some of these features on YouTube:
Watch [**@kentcdodds**](https://github.com/kentcdodds) introduce some of these
features on YouTube:
[![“What is MDX?” on YouTube][what-is-mdx-image]][what-is-mdx]
[quote]: https://twitter.com/chrisbiscardi/status/1022304288326864896
[what-is-mdx-image]: /dev-tips-with-kent.jpg
[what-is-mdx]: https://www.youtube.com/watch?v=d2sQiI5NFAM&list=PLV5CVI1eNcJgCrPH_e6d57KRUTiDZgs0u "I've recently taking a big liking to MDX: A JSX in Markdown loader, parser, and renderer for ambitious projects. It combines the readability of Markdown with the expressivity of JSX. The best of both worlds. 🌐"

View File

@ -1,14 +1,16 @@
# Migrating from v0 to v1
Unfortunately, weve had to introduce a few breaking changes, so weve written a migration guide.
In order to ensure as seamless of an upgrade as possible we plan on supporting v0 for the next
12 months so theres not a huge rush to update (though wed love for you to ASAP) 📆.
Unfortunately, weve had to introduce a few breaking changes, so weve written a
migration guide.
In order to ensure as seamless of an upgrade as possible we plan on supporting
v0 for the next 12 months so theres not a huge rush to update (though wed
love for you to ASAP) 📆.
## ⚠️ Breaking changes
- [🚨`@mdx-js/tag` is replaced by `@mdx-js/react` and an `mdx` pragma](#pragma) 🚨
- [MDXProvider now merges component contexts when nested](#mdxprovider)
- [React support now requires `>= 16.8` in `@mdx-js/react`](#react)
* [🚨`@mdx-js/tag` is replaced by `@mdx-js/react` and an `mdx` pragma](#pragma) 🚨
* [MDXProvider now merges component contexts when nested](#mdxprovider)
* [React support now requires `>= 16.8` in `@mdx-js/react`](#react)
## Pragma
@ -21,15 +23,16 @@ yarn add @mdx-js/react
### Whats different?
The MDXTag implementation has been removed with a custom pragma implementation inspired by
The MDXTag implementation has been removed with a custom pragma implementation
inspired by
[Emotion](https://emotion.sh/docs/css-prop#jsx-pragma).
This ensures that transpiled JSX is more readable and that JSX blocks use the same component
as its markdown counterpart.
It also allows MDXProvider to provide global component scope like a `Youtube` or `Twitter`
component.
This ensures that transpiled JSX is more readable and that JSX blocks use the
same component as its markdown counterpart.
It also allows MDXProvider to provide global component scope like a `Youtube`
or `Twitter` component.
The pragma implementation will also cause JSX HTML elements to be rendered with the component
mapping passed to MDXProvider.
The pragma implementation will also cause JSX HTML elements to be rendered with
the component mapping passed to MDXProvider.
So, the following will result in two identically rendered `h1`s:
```js
@ -42,9 +45,11 @@ So, the following will result in two identically rendered `h1`s:
## MDXProvider
This shouldnt affect most usecases, however if youre nesting component contexts and rely on them not
being merged you will have to use the functional form which allows you to customize the merge.
By ignoring outer context components and returning a new component mapping, you will restore the old behavior:
This shouldnt affect most usecases, however if youre nesting component
contexts and rely on them not being merged you will have to use the functional
form which allows you to customize the merge.
By ignoring outer context components and returning a new component mapping, you
will restore the old behavior:
```js
<MDXProvider components={components}>
@ -56,4 +61,6 @@ By ignoring outer context components and returning a new component mapping, you
## React
Before upgrading to `@mdx-js/mdx@1`, update your website/application to `react@16.8 react-dom@16.8` and ensure it works as expected. Then upgrade to v1.
Before upgrading to `@mdx-js/mdx@1`, update your website/application to
`react@16.8 react-dom@16.8` and ensure it works as expected.
Then upgrade to v1.

View File

@ -7,9 +7,7 @@ Write some MDX code and see it render to the right.
Below, you can also see the output JSX and the intermediary ASTs.
This can be helpful for debugging or exploring how MDX works.
<Editor
children={`# Hello, world!
<Editor children={`# Hello, world!
<button>Here is a button</button>
`}
/>
`}/>

View File

@ -2,44 +2,59 @@
## Apps
- [demoboard][]: The simplest editor alive
* [demoboard][]: The simplest editor alive
## Libraries
- [ok-mdx][]: Browser-based MDX editor
- [docz][]: Documentation framework
- [mdx-deck][]: MDX-based presentation decks
- [mdx-docs][]: Next-based documentation framework
- [mdx-paper][]: MDX-based research articles
- [spectacle-boilerplate-mdx][]: Boilerplate that facilitates using MDX with
* [ok-mdx][]: Browser-based MDX editor
* [docz][]: Documentation framework
* [mdx-deck][]: MDX-based presentation decks
* [mdx-docs][]: Next-based documentation framework
* [mdx-paper][]: MDX-based research articles
* [spectacle-boilerplate-mdx][]: Boilerplate that facilitates using MDX with
Spectacle
- [Charge][]: An opinionated, zero-config static site generator
- [MDNEXT][]: An ecosystem of tools to get your NextJS + MDX projects blasting off
* [Charge][]: An opinionated, zero-config static site generator
* [MDNEXT][]: An ecosystem of tools to get your NextJS + MDX projects blasting
off
## Sites
- [Vercel Docs][vercel-docs]
- [Prisma][]
- [Max Stoibers Blog][mxstbr]
- [SmartRate][smrtrt]
* [Vercel Docs][vercel-docs]
* [Prisma][]
* [Max Stoibers Blog][mxstbr]
* [SmartRate][smrtrt]
## Other related links
- [awesome-mdx][]
- [MDX: content for kings and princesses][mdx-fairy-tale]
* [awesome-mdx][]
* [MDX: content for kings and princesses][mdx-fairy-tale]
[demoboard]: https://frontarm.com/demoboard
[ok-mdx]: https://github.com/jxnblk/ok-mdx
[mdx-deck]: https://github.com/jxnblk/mdx-deck
[mdx-docs]: https://github.com/jxnblk/mdx-docs
[mdx-paper]: https://github.com/hubgit/mdx-paper
[docz]: https://www.docz.site/
[vercel-docs]: https://github.com/zeit/docs
[prisma]: https://www.prisma.io/docs
[mxstbr]: https://mxstbr.com
[smrtrt]: https://www.smartrate.se
[awesome-mdx]: https://github.com/transitive-bullshit/awesome-mdx
[spectacle-boilerplate-mdx]: https://github.com/FormidableLabs/spectacle-boilerplate-mdx
[charge]: https://charge.js.org
[mdx-fairy-tale]: https://github.com/DeveloperMode/mdx-fairy-tale
[mdnext]: https://github.com/domitriusclark/mdnext

View File

@ -14,6 +14,10 @@ free customer service.
## Contents
* [Questions](#questions)
* [Asking quality questions](#asking-quality-questions)
* [Contributions](#contributions)
## Questions
Please chat and ask questions on [Discussions][chat]!
@ -24,30 +28,37 @@ Jump in there and lurk, talk to us, and help others.
Help us help you!
Spending time framing a question and adding support links or resources makes it
much easier for us to help. Its easy to fall into the trap of asking something too
specific when youre close to a problem. Then, those trying to help you out have
to spend a lot of time asking additional questions to understand what you are
hoping to achieve.
much easier for us to help.
Its easy to fall into the trap of asking something too specific when youre
close to a problem.
Then, those trying to help you out have to spend a lot of time asking additional
questions to understand what you are hoping to achieve.
Spending the extra time up front can help save everyone time in the long run.
- Try to define what you need help with:
- Is there something in particular you want to do?
- What problem are you encountering and what steps have you taken to try and fix it?
- Is there a concept youre not understanding?
- Learn about the [rubber duck debugging method][rubberduck]
- Avoid falling for the [XY problem][xy]
- Search on GitHub to see if a similar question has been asked
- Read through the [Getting Started Guide](https://mdxjs.com/getting-started)
- If possible, provide sample code, a [CodeSandbox](https://codesandbox.io), or a video
- The more time you put into asking your question, the better we can help you
* Try to define what you need help with:
* Is there something in particular you want to do?
* What problem are you encountering and what steps have you taken to try
and fix it?
* Is there a concept youre not understanding?
* Learn about the [rubber duck debugging method][rubberduck]
* Avoid falling for the [XY problem][xy]
* Search on GitHub to see if a similar question has been asked
* Read through the [Getting Started Guide](https://mdxjs.com/getting-started)
* If possible, provide sample code, a [CodeSandbox](https://codesandbox.io),
or a video
* The more time you put into asking your question, the better we can help you
## Contributions
[Read the Contributing guidelines on the MDX website][contributing].
[coc]: https://github.com/mdx-js/.github/blob/master/code-of-conduct.md
[rubberduck]: https://rubberduckdebugging.com
[xy]: https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem/66378#66378
[chat]: https://github.com/mdx-js/mdx/discussions
[contributing]: https://mdxjs.com/contributing

View File

@ -3,8 +3,8 @@ export const navSortSelf = 3
# Table of components
[`MDXProvider`](/getting-started/#mdxprovider) uses React Context to provide the component mapping
internally to MDX when it renders.
[`MDXProvider`](/getting-started/#mdxprovider) uses React Context to provide
the component mapping internally to MDX when it renders.
The following components are rendered from Markdown, so these can be keys in the
component object you pass to `MDXProvider`.

View File

@ -14,6 +14,7 @@
"@mdx-js/mdx": "^1.0.0",
"@mdx-js/react": "^1.0.0",
"@mdx-js/runtime": "^1.0.0",
"esbuild-register": "^3.0.0",
"ink": "^3.0.0",
"react": "^17.0.0"
}

View File

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2017-2020 Compositor and Vercel, Inc.
Copyright (c) 2017 Compositor and Vercel, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

7704
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,14 @@
{
"repository": "mdx-js/mdx",
"private": true,
"name": "monorepo",
"license": "MIT",
"homepage": "https://mdxjs.com",
"repository": "mdx-js/mdx",
"bugs": "https://github.com/mdx-js/mdx/issues",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
},
"license": "MIT",
"private": true,
"type": "module",
"workspaces": [
"packages/react",
@ -23,29 +24,6 @@
"examples/terminal",
"examples/webpack"
],
"scripts": {
"postinstall": "patch-package",
"prepare": "husky install",
"clean": "npm exec -c \"rimraf node_modules\" --workspaces",
"docs-prep": "node website/prep.js && postcss docs/_asset/index.css -o public/index.css",
"docs-bundle-dev": "NODE_ENV=development node website/bundle.js",
"docs-bundle-prod": "NODE_ENV=production node website/bundle.js",
"docs-generate": "NODE_LOADER_CONFIG=website/loader-react-server.js node --no-warnings --experimental-loader @node-loader/core --conditions=react-server website/generate.server.js",
"docs-prerender": "NODE_LOADER_CONFIG=website/loader.js node --no-warnings --experimental-loader @node-loader/core website/prerender.js",
"docs-post": "node --trace-warnings website/post.js",
"docs-dev": "npm run docs-prep && npm run docs-bundle-dev && npm run docs-generate && npm run docs-prerender && npm run docs-post",
"docs-prod": "npm run docs-prep && npm run docs-bundle-prod && npm run docs-generate && npm run docs-prerender && npm run docs-post",
"docs": "npm run docs-prod",
"docs-deploy": "vercel && vercel alias $(pbpaste) mdxjs.com && vercel alias $(pbpaste) www.mdxjs.com",
"format": "npm run lint -- --fix",
"lint": "eslint --ext .jsx --report-unused-disable-directives --cache .",
"publish-ci": "# lerna publish -y --canary --preid ci --pre-dist-tag ci",
"publish-next": "# lerna publish --force-publish=\"*\" --pre-dist-tag next --preid next",
"build": "npm run build --workspaces -w packages/remark-mdx -w packages/mdx -w packages/react -w packages/preact -w packages/vue -w packages/loader --if-present",
"test-api": "npm run test-api --workspaces --if-present",
"test-coverage": "npm run test-coverage --workspaces --if-present",
"test": "npm run build && npm run lint && npm run test-coverage"
},
"devDependencies": {
"@babel/core": "^7.0.0",
"@babel/plugin-syntax-jsx": "^7.0.0",
@ -69,7 +47,6 @@
"cssnano": "^5.0.0",
"dlv": "^1.0.0",
"esbuild": "^0.12.0",
"esbuild-register": "^3.0.0",
"eslint": "^7.0.0",
"eslint-config-prettier": "^8.0.0",
"eslint-config-xo": "^0.38.0",
@ -113,12 +90,13 @@
"rehype-shift-heading": "^1.0.0",
"rehype-slug": "^5.0.0",
"rehype-stringify": "^9.0.0",
"remark-cli": "^10.0.0",
"remark-frontmatter": "^4.0.0",
"remark-gemoji": "^7.0.0",
"remark-gfm": "^2.0.0",
"remark-github": "^11.0.0",
"remark-mdx-frontmatter": "^1.0.0",
"remark-preset-wooorm": "^8.0.0",
"remark-preset-wooorm": "^9.0.0",
"remark-toc": "^8.0.0",
"rimraf": "^3.0.0",
"rodemirror": "^1.0.0",
@ -138,11 +116,34 @@
"xast-util-to-xml": "^3.0.0",
"xdm": "^2.0.0"
},
"scripts": {
"postinstall": "patch-package",
"prepare": "husky install",
"clean": "npm exec -c \"rimraf node_modules\" --workspaces",
"docs-prep": "node website/prep.js && postcss docs/_asset/index.css -o public/index.css",
"docs-bundle-dev": "NODE_ENV=development node website/bundle.js",
"docs-bundle-prod": "NODE_ENV=production node website/bundle.js",
"docs-generate": "NODE_LOADER_CONFIG=website/loader-react-server.js node --no-warnings --experimental-loader @node-loader/core --conditions=react-server website/generate.server.js",
"docs-prerender": "NODE_LOADER_CONFIG=website/loader.js node --no-warnings --experimental-loader @node-loader/core website/prerender.js",
"docs-post": "node --trace-warnings website/post.js",
"docs-dev": "npm run docs-prep && npm run docs-bundle-dev && npm run docs-generate && npm run docs-prerender && npm run docs-post",
"docs-prod": "npm run docs-prep && npm run docs-bundle-prod && npm run docs-generate && npm run docs-prerender && npm run docs-post",
"docs": "npm run docs-prod",
"docs-deploy": "vercel && vercel alias $(pbpaste) mdxjs.com && vercel alias $(pbpaste) www.mdxjs.com",
"format": "npm run lint -- --fix",
"lint": "remark . -qfo && remark . -e mdx -u mdx -qfo && prettier . -w --loglevel warn && eslint --ext .jsx --report-unused-disable-directives --cache .",
"publish-ci": "# lerna publish -y --canary --preid ci --pre-dist-tag ci",
"publish-next": "# lerna publish --force-publish=\"*\" --pre-dist-tag next --preid next",
"build": "npm run build --workspaces -w packages/remark-mdx -w packages/mdx -w packages/react -w packages/preact -w packages/vue -w packages/loader --if-present",
"test-api": "npm run test-api --workspaces --if-present",
"test-coverage": "npm run test-coverage --workspaces --if-present",
"test": "npm run build && npm run lint && npm run test-coverage"
},
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"eslint --fix --report-unused-disable-directives --cache"
],
"*.{css,html,json,ts,tsx,yml}": [
"*.{css,html,json,js,jsx,ts,tsx,yml}": [
"prettier --write"
]
},
@ -150,14 +151,6 @@
"last 2 versions",
"not dead"
],
"postcss": {
"plugins": {
"autoprefixer": true,
"cssnano": {
"preset": "default"
}
}
},
"prettier": {
"arrowParens": "avoid",
"tabWidth": 2,
@ -166,5 +159,22 @@
"bracketSpacing": false,
"semi": false,
"trailingComma": "none"
},
"postcss": {
"plugins": {
"autoprefixer": true,
"cssnano": {
"preset": "default"
}
}
},
"remarkConfig": {
"plugins": [
"preset-wooorm",
[
"lint-file-extension",
false
]
]
}
}

View File

@ -10,7 +10,7 @@
module.exports = function (code) {
const callback = this.async()
// Note that `import()` caches, so this should be fast enough.
import('./lib/index.js').then((module) =>
import('./lib/index.js').then(module =>
module.loader.call(this, code, callback)
)
}

View File

@ -1,5 +1,7 @@
/**
* @todo use `JSX` instead of `react`, to support Preact, Vue, etc?
* @todo
* Land <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/55809>
* for runtime-agnostic types.
*/
type LoaderContext = import('webpack').LoaderContext<unknown>

View File

@ -22,12 +22,14 @@ export function loader(value, callback) {
// @ts-expect-error: types for webpack/loader-utils are out of sync.
const options = {...getOptions(this)}
/* c8 ignore next 3 */
/* c8 ignore next 5 */
if ('renderer' in options) {
throw new Error('`options.renderer` is no longer supported. Please see <https://mdxjs.com/migrating/v2/> for more information')
throw new Error(
'`options.renderer` is no longer supported. Please see <https://mdxjs.com/migrating/v2/> for more information'
)
}
compile({value, path: this.resourcePath}, options).then((file) => {
compile({value, path: this.resourcePath}, options).then(file => {
// @ts-expect-error conflict between UInt8Array and Buffer is expected, and a tradeoff made in vfile typings to avoid `@types/node` being required
callback(null, file.value, file.map)
return file

View File

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2017-2018 Compositor and Vercel, Inc.
Copyright (c) 2017 Compositor and Vercel, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -119,21 +119,39 @@ abide by its terms.
[MIT][] © [Compositor][] and [Vercel][]
[build-badge]: https://github.com/mdx-js/mdx/workflows/CI/badge.svg
[build]: https://github.com/mdx-js/mdx/actions
[downloads-badge]: https://img.shields.io/npm/dm/@mdx-js/loader.svg
[downloads]: https://www.npmjs.com/package/@mdx-js/loader
[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg
[backers-badge]: https://opencollective.com/unified/backers/badge.svg
[opencollective]: https://opencollective.com/unified
[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg
[chat]: https://github.com/mdx-js/mdx/discussions
[npm]: https://docs.npmjs.com/cli/install
[yarn]: https://yarnpkg.com/cli/add
[contributing]: https://mdxjs.com/contributing
[support]: https://mdxjs.com/support
[coc]: https://github.com/mdx-js/.github/blob/master/code-of-conduct.md
[mit]: license
[compositor]: https://compositor.io
[vercel]: https://vercel.com
[mdx]: https://github.com/mdx-js/mdx
[custom-pragma]: https://mdxjs.com/blog/custom-pragma

View File

@ -35,8 +35,19 @@ test('@mdx-js/loader', async () => {
context: fileURLToPath(base),
entry: './webpack.mdx',
mode: 'none',
module: {rules: [{test: /\.mdx$/, use: [fileURLToPath(new URL('../index.cjs', import.meta.url))]}]},
output: {path: fileURLToPath(base), filename: 'react.cjs', libraryTarget: 'commonjs'}
module: {
rules: [
{
test: /\.mdx$/,
use: [fileURLToPath(new URL('../index.cjs', import.meta.url))]
}
]
},
output: {
path: fileURLToPath(base),
filename: 'react.cjs',
libraryTarget: 'commonjs'
}
})
// One for ESM loading CJS, one for webpack.
@ -60,7 +71,9 @@ test('@mdx-js/loader', async () => {
context: fileURLToPath(base),
entry: './webpack.mdx',
mode: 'none',
module: {rules: [{
module: {
rules: [
{
test: /\.mdx$/,
use: [
{
@ -68,8 +81,14 @@ test('@mdx-js/loader', async () => {
options: {jsxImportSource: 'preact'}
}
]
}]},
output: {path: fileURLToPath(base), filename: 'preact.cjs', libraryTarget: 'commonjs'}
}
]
},
output: {
path: fileURLToPath(base),
filename: 'preact.cjs',
libraryTarget: 'commonjs'
}
})
// One for ESM loading CJS, one for webpack.
@ -94,14 +113,28 @@ test('@mdx-js/loader', async () => {
entry: './webpack.mdx',
mode: 'none',
externals: ['vue'],
module: {rules: [{
module: {
rules: [
{
test: /\.mdx$/,
use: [
{loader: 'babel-loader', options: {configFile: false, plugins: ['@vue/babel-plugin-jsx']}},
{loader: fileURLToPath(new URL('../index.cjs', import.meta.url)), options: {jsx: true}}
{
loader: 'babel-loader',
options: {configFile: false, plugins: ['@vue/babel-plugin-jsx']}
},
{
loader: fileURLToPath(new URL('../index.cjs', import.meta.url)),
options: {jsx: true}
}
]
}]},
output: {path: fileURLToPath(base), filename: 'vue.cjs', libraryTarget: 'commonjs'}
}
]
},
output: {
path: fileURLToPath(base),
filename: 'vue.cjs',
libraryTarget: 'commonjs'
}
})
// One for ESM loading CJS, one for webpack.
@ -111,8 +144,12 @@ test('@mdx-js/loader', async () => {
(await import('./vue.cjs')).default.default
)
const vueResult = await serverRenderer.renderToString(vue.createSSRApp({components: {Content: ContentVue}, template: '<Content />'}))
const vueResult = await serverRenderer.renderToString(
vue.createSSRApp({
components: {Content: ContentVue},
template: '<Content />'
})
)
assert.equal(
// Remove SSR comments used to hydrate (I guess).
@ -127,5 +164,4 @@ test('@mdx-js/loader', async () => {
await fs.unlink(new URL('webpack.mdx', base))
})
test.run()

View File

@ -156,7 +156,7 @@ export function recmaDocument(options = {}) {
const source = child.source
// Remove `default` or `as default`, but not `default as`, specifier.
child.specifiers = child.specifiers.filter((specifier) => {
child.specifiers = child.specifiers.filter(specifier => {
if (specifier.exported.name === 'default') {
if (layout) {
file.fail(
@ -257,7 +257,7 @@ export function recmaDocument(options = {}) {
argument: {type: 'Identifier', name: '_exportAll' + (index + 1)}
})
),
...exportedIdentifiers.map((d) => {
...exportedIdentifiers.map(d => {
/** @type {Property} */
const prop = {
type: 'Property',
@ -423,9 +423,9 @@ export function recmaDocument(options = {}) {
/** @type {Array.<VariableDeclarator>} */
const declarators = node.specifiers
.filter(
(specifier) => specifier.local.name !== specifier.exported.name
specifier => specifier.local.name !== specifier.exported.name
)
.map((specifier) => ({
.map(specifier => ({
type: 'VariableDeclarator',
id: specifier.exported,
init: specifier.local

View File

@ -17,7 +17,7 @@ import {specifiersToObjectPattern} from '../util/estree-util-specifiers-to-objec
export function recmaJsxBuild(options = {}) {
const {outputFormat} = options
return (tree) => {
return tree => {
buildJsx(tree)
// When compiling to a function body, replace the import that was just

View File

@ -45,7 +45,7 @@ import {specifiersToObjectPattern} from '../util/estree-util-specifiers-to-objec
export function recmaJsxRewrite(options = {}) {
const {providerImportSource, outputFormat} = options
return (tree) => {
return tree => {
// Find everything thats defined in the top-level scope.
const scopeInfo = analyze(tree)
/** @type {Array.<StackEntry>} */
@ -248,7 +248,7 @@ export function recmaJsxRewrite(options = {}) {
type: 'VariableDeclarator',
id: {
type: 'ObjectPattern',
properties: actual.map((name) => ({
properties: actual.map(name => ({
type: 'Property',
kind: 'init',
key: {

View File

@ -50,7 +50,9 @@ export function recmaStringify(options = {}) {
}
const result = generate(tree, {
generator: { ...baseGenerator, JSXAttribute,
generator: {
...baseGenerator,
JSXAttribute,
JSXClosingElement,
JSXClosingFragment,
JSXElement,
@ -63,7 +65,8 @@ export function recmaStringify(options = {}) {
JSXOpeningElement,
JSXOpeningFragment,
JSXSpreadAttribute,
JSXText},
JSXText
},
comments: true,
sourceMap
})
@ -316,7 +319,7 @@ function JSXSpreadAttribute(node, state) {
*/
function JSXText(node, state) {
state.write(
encodeJsx(node.value).replace(/<|{/g, ($0) =>
encodeJsx(node.value).replace(/<|{/g, $0 =>
$0 === '<' ? '&lt;' : '&#123;'
),
node

View File

@ -12,5 +12,5 @@ import {toEstree} from 'hast-util-to-estree'
* @type {import('unified').Plugin<void[], Root, Program>}
*/
export function rehypeRecma() {
return (tree) => toEstree(tree)
return tree => toEstree(tree)
}

View File

@ -12,7 +12,7 @@ import {visit} from 'unist-util-visit'
* @type {import('unified').Plugin<void[], Root>}
*/
export function rehypeRemoveRaw() {
return (tree) => {
return tree => {
visit(tree, 'raw', (_, index, parent) => {
if (parent && typeof index === 'number') {
parent.children.splice(index, 1)

View File

@ -18,7 +18,7 @@ import {visit} from 'unist-util-visit'
* @type {import('unified').Plugin<void[], Root>}
*/
export function remarkMarkAndUnravel() {
return (tree) => {
return tree => {
visit(tree, (node, index, parent_) => {
const parent = /** @type {Parent} */ (parent_)
let offset = -1

View File

@ -16,7 +16,7 @@ import {create} from './estree-util-create.js'
export function specifiersToObjectPattern(specifiers) {
return {
type: 'ObjectPattern',
properties: specifiers.map((specifier) => {
properties: specifiers.map(specifier => {
/** @type {Identifier} */
let key =
specifier.type === 'ImportSpecifier'

View File

@ -6,6 +6,6 @@
*/
export function extnamesToRegex(extnames) {
return new RegExp(
'\\.(' + extnames.map((d) => d.slice(1)).join('|') + ')([?#]|$)'
'\\.(' + extnames.map(d => d.slice(1)).join('|') + ')([?#]|$)'
)
}

View File

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2017-2019 Compositor, Inc. and Vercel, Inc.
Copyright (c) 2017 Compositor, Inc. and Vercel, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -52,15 +52,27 @@ abide by its terms.
[MIT][] © [Compositor][] and [Vercel][]
[build]: https://travis-ci.com/mdx-js/mdx
[build-badge]: https://travis-ci.com/mdx-js/mdx.svg?branch=master
[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg
[chat]: https://github.com/mdx-js/mdx/discussions
[contributing]: https://mdxjs.com/contributing
[support]: https://mdxjs.com/support
[coc]: https://github.com/mdx-js/.github/blob/master/code-of-conduct.md
[mit]: license
[remark]: https://github.com/remarkjs/remark
[compositor]: https://compositor.io
[vercel]: https://vercel.com
[mdx]: https://github.com/mdx-js/mdx
[npm]: https://docs.npmjs.com/cli/install

View File

@ -22,7 +22,10 @@ test('should generate JSX', async () => {
test('should compile JSX to function calls', async () => {
const result = await compile('Hello World')
assert.match(result, /_jsx\(_components\.p, {\s+children: "Hello World"\s+}\)/)
assert.match(
result,
/_jsx\(_components\.p, {\s+children: "Hello World"\s+}\)/
)
})
test('should generate runnable JS', async () => {
@ -46,7 +49,10 @@ test('should support `&`, `<`, and `>` in text', async () => {
})
test('should generate JSX-compliant strings', async () => {
const {default: Content} = await evaluate('!["so" cute](cats.com/cat.jpeg)', runtime)
const {default: Content} = await evaluate(
'!["so" cute](cats.com/cat.jpeg)',
runtime
)
// Note: Escaped quotes (\") isn't valid for JSX string syntax. So we're
// making sure that quotes aren't escaped here (prettier doesn't like us
@ -63,7 +69,10 @@ test('should generate JSX-compliant strings', async () => {
})
test('should support `remarkPlugins` (math)', async () => {
const {default: Content} = await evaluate('$x$', {remarkPlugins: [math], ...runtime})
const {default: Content} = await evaluate('$x$', {
remarkPlugins: [math],
...runtime
})
assert.equal(
renderToStaticMarkup(<Content />),
@ -76,7 +85,10 @@ test('should support `remarkPlugins` (math)', async () => {
})
test('should support `remarkPlugins` (footnotes)', async () => {
const {default: Content} = await evaluate('x [^y]\n\n[^y]: z', {remarkPlugins: [footnotes], ...runtime})
const {default: Content} = await evaluate('x [^y]\n\n[^y]: z', {
remarkPlugins: [footnotes],
...runtime
})
assert.equal(
renderToStaticMarkup(<Content />),
@ -84,17 +96,31 @@ test('should support `remarkPlugins` (footnotes)', async () => {
<>
<p>
x{' '}
<a href="#fn1" className="footnote-ref" id="fnref1" role="doc-noteref">
<sup>
1
</sup>
<a
href="#fn1"
className="footnote-ref"
id="fnref1"
role="doc-noteref"
>
<sup>1</sup>
</a>
</p>{'\n'}
<section className="footnotes" role="doc-endnotes">{'\n'}
<hr />{'\n'}
<ol>{'\n'}
<li id="fn1" role="doc-endnote">z<a href="#fnref1" className="footnote-back" role="doc-backlink"></a></li>{'\n'}
</ol>{'\n'}
</p>
{'\n'}
<section className="footnotes" role="doc-endnotes">
{'\n'}
<hr />
{'\n'}
<ol>
{'\n'}
<li id="fn1" role="doc-endnote">
z
<a href="#fnref1" className="footnote-back" role="doc-backlink">
</a>
</li>
{'\n'}
</ol>
{'\n'}
</section>
</>
)
@ -145,7 +171,10 @@ test('should support async plugins', async () => {
tree.children[0].children[0].value = 'y'
}
const {default: Content} = await evaluate('x', {remarkPlugins: [plugin], ...runtime})
const {default: Content} = await evaluate('x', {
remarkPlugins: [plugin],
...runtime
})
assert.equal(
renderToStaticMarkup(<Content />),
@ -174,7 +203,6 @@ test('should use an `inlineCode` “element” in mdxhast', async () => {
)
})
test('should support `pre`/`code` from empty fenced code', async () => {
const {default: Content} = await evaluate('```\n```', runtime)
@ -220,11 +248,13 @@ test('should support a block quote in markdown', async () => {
assert.equal(
renderToStaticMarkup(<Content />),
renderToStaticMarkup(
<blockquote>{'\n'}
<blockquote>
{'\n'}
<p>
x{'\n'}
<code>y</code>
</p>{'\n'}
</p>
{'\n'}
</blockquote>
)
)
@ -244,7 +274,10 @@ test('should support html/jsx inside code in markdown', async () => {
})
test('should support tables in markdown', async () => {
const {default: Content} = await evaluate('| A | B |\n| :- | -: |\n| a | b |', {remarkPlugins: [gfm], ...runtime})
const {default: Content} = await evaluate(
'| A | B |\n| :- | -: |\n| a | b |',
{remarkPlugins: [gfm], ...runtime}
)
assert.equal(
renderToStaticMarkup(<Content />),
@ -299,14 +332,20 @@ test('should support an empty document', async () => {
test('should support an ignored node instead of a `root`', async () => {
const plugin = () => () => ({type: 'doctype', name: 'html'})
const {default: Content} = await evaluate('', {rehypePlugins: [plugin], ...runtime})
const {default: Content} = await evaluate('', {
rehypePlugins: [plugin],
...runtime
})
assert.equal(renderToStaticMarkup(<Content />), renderToStaticMarkup(<></>))
})
test('should support an element instead of a `root`', async () => {
const plugin = () => () => ({type: 'element', tagName: 'x', children: []})
const {default: Content} = await evaluate('', {rehypePlugins: [plugin], ...runtime})
const {default: Content} = await evaluate('', {
rehypePlugins: [plugin],
...runtime
})
assert.equal(renderToStaticMarkup(<Content />), renderToStaticMarkup(<x />))
})
@ -343,7 +382,10 @@ test('should crash on incorrect imports', async () => {
await compile('import a')
assert.unreachable('should not compile')
} catch (error) {
assert.match(String(error), /Could not parse import\/exports with acorn: SyntaxError: Unexpected token/)
assert.match(
String(error),
/Could not parse import\/exports with acorn: SyntaxError: Unexpected token/
)
}
})
@ -354,11 +396,16 @@ test('should support import as a word when its not the top level', async () =
renderToStaticMarkup(<Content />),
renderToStaticMarkup(
<>
<blockquote>{'\n'}
<p>import a</p>{'\n'}
</blockquote>{'\n'}
<ul>{'\n'}
<li>import b</li>{'\n'}
<blockquote>
{'\n'}
<p>import a</p>
{'\n'}
</blockquote>
{'\n'}
<ul>
{'\n'}
<li>import b</li>
{'\n'}
</ul>
</>
)
@ -399,7 +446,10 @@ test('should crash on incorrect exports', async () => {
await compile('export a')
assert.unreachable('should not compile')
} catch (error) {
assert.match(String(error), /Could not parse import\/exports with acorn: SyntaxError: Unexpected token/)
assert.match(
String(error),
/Could not parse import\/exports with acorn: SyntaxError: Unexpected token/
)
}
})
@ -410,11 +460,16 @@ test('should support export as a word when its not the top level', async () =
renderToStaticMarkup(<Content />),
renderToStaticMarkup(
<>
<blockquote>{'\n'}
<p>export a</p>{'\n'}
</blockquote>{'\n'}
<ul>{'\n'}
<li>export b</li>{'\n'}
<blockquote>
{'\n'}
<p>export a</p>
{'\n'}
</blockquote>
{'\n'}
<ul>
{'\n'}
<li>export b</li>
{'\n'}
</ul>
</>
)
@ -463,7 +518,10 @@ test('should support JSX expressions (text, inline)', async () => {
})
test('should support a default export for a layout', async () => {
const {default: Content} = await evaluate('export default props => <main {...props} />\n\nx', runtime)
const {default: Content} = await evaluate(
'export default props => <main {...props} />\n\nx',
runtime
)
assert.equal(
renderToStaticMarkup(<Content />),
@ -503,7 +561,10 @@ test('should support a default export from an import', async () => {
})
test('should support semicolons in the default export', async () => {
const {default: Content} = await evaluate('export default props => <section {...props} />;\n\nx', runtime)
const {default: Content} = await evaluate(
'export default props => <section {...props} />;\n\nx',
runtime
)
assert.equal(
renderToStaticMarkup(<Content />),
@ -516,7 +577,10 @@ test('should support semicolons in the default export', async () => {
})
test('should support a multiline default export', async () => {
const {default: Content} = await evaluate('export default ({children}) => (\n <article>\n {children}\n </article>\n)\n\nx', runtime)
const {default: Content} = await evaluate(
'export default ({children}) => (\n <article>\n {children}\n </article>\n)\n\nx',
runtime
)
assert.equal(
renderToStaticMarkup(<Content />),
@ -529,13 +593,19 @@ test('should support a multiline default export', async () => {
})
test('should support using a non-default export in content', async () => {
const {default: Content} = await evaluate('export var X = props => <b {...props} />\n\n<X />', runtime)
const {default: Content} = await evaluate(
'export var X = props => <b {...props} />\n\n<X />',
runtime
)
assert.equal(renderToStaticMarkup(<Content />), renderToStaticMarkup(<b />))
})
test('should support overwriting missing compile-time components at run-time', async () => {
const {default: Content} = await evaluate('x <Y /> z', {...runtime, useMDXComponents})
const {default: Content} = await evaluate('x <Y /> z', {
...runtime,
useMDXComponents
})
assert.equal(
renderToStaticMarkup(
@ -580,7 +650,10 @@ test('should throw when an undefined component is used', async () => {
})
test('should support `.` in component names for members', async () => {
const {default: Content} = await evaluate('export var x = {y: props => <b {...props} />}\n\n<x.y />', runtime)
const {default: Content} = await evaluate(
'export var x = {y: props => <b {...props} />}\n\n<x.y />',
runtime
)
assert.equal(renderToStaticMarkup(<Content />), renderToStaticMarkup(<b />))
})
@ -614,7 +687,10 @@ test('should support `element` nodes w/o `properties` in mdxhast', async () => {
})
}
const {default: Content} = await evaluate('x', {rehypePlugins: [plugin], ...runtime})
const {default: Content} = await evaluate('x', {
rehypePlugins: [plugin],
...runtime
})
assert.equal(
renderToStaticMarkup(<Content />),
@ -663,14 +739,14 @@ test('should support an escaped dollar in text', async () => {
test('should support an empty expression in JSX', async () => {
const {default: Content} = await evaluate('<x>{}</x>', runtime)
assert.equal(
renderToStaticMarkup(<Content />),
renderToStaticMarkup(<x />)
)
assert.equal(renderToStaticMarkup(<Content />), renderToStaticMarkup(<x />))
})
test('should support a more complex expression in JSX', async () => {
const {default: Content} = await evaluate('<x>{(() => 1 + 2)(1)}</x>', runtime)
const {default: Content} = await evaluate(
'<x>{(() => 1 + 2)(1)}</x>',
runtime
)
assert.equal(
renderToStaticMarkup(<Content />),
@ -679,7 +755,10 @@ test('should support a more complex expression in JSX', async () => {
})
test('default: should be async', async () => {
assert.match(await compile('x', {jsx: true}), /<_components\.p>{"x"}<\/_components\.p>/)
assert.match(
await compile('x', {jsx: true}),
/<_components\.p>{"x"}<\/_components\.p>/
)
})
test('default: should support `remarkPlugins`', async () => {
@ -690,26 +769,30 @@ test('default: should support `remarkPlugins`', async () => {
})
test('sync: should be sync', () => {
assert.match(compileSync('x', {jsx: true}), /<_components\.p>{"x"}<\/_components\.p>/)
assert.match(
compileSync('x', {jsx: true}),
/<_components\.p>{"x"}<\/_components\.p>/
)
})
test('sync: should support `remarkPlugins`', () => {
assert.match(compileSync('$x$', {remarkPlugins: [math], jsx: true}), /className="math math-inline"/)
assert.match(
compileSync('$x$', {remarkPlugins: [math], jsx: true}),
/className="math math-inline"/
)
})
test('should create a unified processor', async () => {
const remarkPlugin = () => (tree) => {
const remarkPlugin = () => tree => {
const clone = removePosition(JSON.parse(JSON.stringify(tree)), true)
assert.equal(clone, {
type: 'root',
children: [
{ type: 'paragraph', children: [ { type: 'text', value: 'x' } ] }
]
children: [{type: 'paragraph', children: [{type: 'text', value: 'x'}]}]
})
}
const rehypePlugin = () => (tree) => {
const rehypePlugin = () => tree => {
const clone = removePosition(JSON.parse(JSON.stringify(tree)), true)
assert.equal(clone, {
@ -731,7 +814,10 @@ test('should create a unified processor', async () => {
jsx: true
})
assert.match(await processor.process('x'), /<_components\.p>{"x"}<\/_components\.p>/)
assert.match(
await processor.process('x'),
/<_components\.p>{"x"}<\/_components\.p>/
)
})
test.run()

View File

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2017-2018 Compositor and Vercel, Inc.
Copyright (c) 2017 Compositor and Vercel, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -83,20 +83,37 @@ abide by its terms.
[MIT][] © [Compositor][] and [Vercel][]
[build-badge]: https://github.com/mdx-js/mdx/workflows/CI/badge.svg
[build]: https://github.com/mdx-js/mdx/actions
[downloads-badge]: https://img.shields.io/npm/dm/@mdx-js/preact.svg
[downloads]: https://www.npmjs.com/package/@mdx-js/preact
[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg
[backers-badge]: https://opencollective.com/unified/backers/badge.svg
[opencollective]: https://opencollective.com/unified
[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg
[chat]: https://github.com/mdx-js/mdx/discussions
[mdx]: https://mdxjs.com
[npm]: https://docs.npmjs.com/cli/install
[yarn]: https://yarnpkg.com/cli/add
[contributing]: https://mdxjs.com/contributing
[support]: https://mdxjs.com/support
[coc]: https://github.com/mdx-js/.github/blob/master/code-of-conduct.md
[mit]: license
[compositor]: https://compositor.io
[vercel]: https://vercel.com

View File

@ -9,7 +9,10 @@ import {evaluate} from '@mdx-js/mdx'
import {MDXProvider, useMDXComponents, withMDXComponents} from '../index.js'
test('should support `components` with `MDXProvider`', async () => {
const {default: Content} = await evaluate('# hi', {...runtime, useMDXComponents})
const {default: Content} = await evaluate('# hi', {
...runtime,
useMDXComponents
})
assert.equal(
render(
@ -26,7 +29,10 @@ test('should support `components` with `MDXProvider`', async () => {
})
test('should support `wrapper` in `components`', async () => {
const {default: Content} = await evaluate('# hi', {...runtime, useMDXComponents})
const {default: Content} = await evaluate('# hi', {
...runtime,
useMDXComponents
})
assert.equal(
render(
@ -43,7 +49,10 @@ test('should support `wrapper` in `components`', async () => {
})
test('should combine components in nested `MDXProvider`s', async () => {
const {default: Content} = await evaluate('# hi\n## hello', {...runtime, useMDXComponents})
const {default: Content} = await evaluate('# hi\n## hello', {
...runtime,
useMDXComponents
})
assert.equal(
render(
@ -67,7 +76,10 @@ test('should combine components in nested `MDXProvider`s', async () => {
})
test('should support components as a function', async () => {
const {default: Content} = await evaluate('# hi\n## hello', {...runtime, useMDXComponents})
const {default: Content} = await evaluate('# hi\n## hello', {
...runtime,
useMDXComponents
})
assert.equal(
render(
@ -91,7 +103,10 @@ test('should support components as a function', async () => {
})
test('should support a `disableParentContext` prop (sandbox)', async () => {
const {default: Content} = await evaluate('# hi', {...runtime, useMDXComponents})
const {default: Content} = await evaluate('# hi', {
...runtime,
useMDXComponents
})
assert.equal(
render(
@ -110,7 +125,10 @@ test('should support a `disableParentContext` prop (sandbox)', async () => {
})
test('should support `withComponents`', async () => {
const {default: Content} = await evaluate('# hi\n## hello', {...runtime, useMDXComponents})
const {default: Content} = await evaluate('# hi\n## hello', {
...runtime,
useMDXComponents
})
const With = withMDXComponents(props => <>{props.children}</>)
// To do: should this use the `h2` component too?

View File

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2017-2018 Compositor and Vercel, Inc.
Copyright (c) 2017 Compositor and Vercel, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -74,20 +74,37 @@ abide by its terms.
[MIT][] © [Compositor][] and [Vercel][]
[build-badge]: https://github.com/mdx-js/mdx/workflows/CI/badge.svg
[build]: https://github.com/mdx-js/mdx/actions
[downloads-badge]: https://img.shields.io/npm/dm/@mdx-js/react.svg
[downloads]: https://www.npmjs.com/package/@mdx-js/react
[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg
[backers-badge]: https://opencollective.com/unified/backers/badge.svg
[opencollective]: https://opencollective.com/unified
[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg
[chat]: https://github.com/mdx-js/mdx/discussions
[mdx]: https://mdxjs.com
[npm]: https://docs.npmjs.com/cli/install
[yarn]: https://yarnpkg.com/cli/add
[contributing]: https://mdxjs.com/contributing
[support]: https://mdxjs.com/support
[coc]: https://github.com/mdx-js/.github/blob/master/code-of-conduct.md
[mit]: license
[compositor]: https://compositor.io
[vercel]: https://vercel.com

View File

@ -7,7 +7,10 @@ import {renderToString} from 'react-dom/server.js'
import {MDXProvider, useMDXComponents, withMDXComponents} from '../index.js'
test('should support `components` with `MDXProvider`', async () => {
const {default: Content} = await evaluate('# hi', {...runtime, useMDXComponents})
const {default: Content} = await evaluate('# hi', {
...runtime,
useMDXComponents
})
assert.equal(
renderToString(
@ -24,7 +27,10 @@ test('should support `components` with `MDXProvider`', async () => {
})
test('should support `wrapper` in `components`', async () => {
const {default: Content} = await evaluate('# hi', {...runtime, useMDXComponents})
const {default: Content} = await evaluate('# hi', {
...runtime,
useMDXComponents
})
assert.equal(
renderToString(
@ -41,7 +47,10 @@ test('should support `wrapper` in `components`', async () => {
})
test('should combine components in nested `MDXProvider`s', async () => {
const {default: Content} = await evaluate('# hi\n## hello', {...runtime, useMDXComponents})
const {default: Content} = await evaluate('# hi\n## hello', {
...runtime,
useMDXComponents
})
assert.equal(
renderToString(
@ -65,7 +74,10 @@ test('should combine components in nested `MDXProvider`s', async () => {
})
test('should support components as a function', async () => {
const {default: Content} = await evaluate('# hi\n## hello', {...runtime, useMDXComponents})
const {default: Content} = await evaluate('# hi\n## hello', {
...runtime,
useMDXComponents
})
assert.equal(
renderToString(
@ -89,7 +101,10 @@ test('should support components as a function', async () => {
})
test('should support a `disableParentContext` prop (sandbox)', async () => {
const {default: Content} = await evaluate('# hi', {...runtime, useMDXComponents})
const {default: Content} = await evaluate('# hi', {
...runtime,
useMDXComponents
})
assert.equal(
renderToString(
@ -108,7 +123,10 @@ test('should support a `disableParentContext` prop (sandbox)', async () => {
})
test('should support `withComponents`', async () => {
const {default: Content} = await evaluate('# hi\n## hello', {...runtime, useMDXComponents})
const {default: Content} = await evaluate('# hi\n## hello', {
...runtime,
useMDXComponents
})
const With = withMDXComponents(props => <>{props.children}</>)
// To do: should this use the `h2` component too?

View File

@ -122,15 +122,15 @@ attacks.
## Related
- [`remark-breaks`](https://github.com/remarkjs/remark-breaks)
* [`remark-breaks`](https://github.com/remarkjs/remark-breaks)
— More breaks
- [`remark-footnotes`](https://github.com/remarkjs/remark-footnotes)
* [`remark-footnotes`](https://github.com/remarkjs/remark-footnotes)
— Footnotes support
- [`remark-frontmatter`](https://github.com/remarkjs/remark-frontmatter)
* [`remark-frontmatter`](https://github.com/remarkjs/remark-frontmatter)
— Frontmatter (yaml, toml, and more) support
- [`remark-github`](https://github.com/remarkjs/remark-github)
* [`remark-github`](https://github.com/remarkjs/remark-github)
— References to issues, PRs, comments, users, etc
- [`remark-math`](https://github.com/rokt33r/remark-math)
* [`remark-math`](https://github.com/rokt33r/remark-math)
— Inline and block math
## Contribute
@ -147,24 +147,45 @@ abide by its terms.
[MIT][license] © [Titus Wormer][author]
[build-badge]: https://img.shields.io/travis/mdx-js/mdx/master.svg
[build]: https://travis-ci.org/mdx-js/mdx
[downloads-badge]: https://img.shields.io/npm/dm/remark-mdx.svg
[downloads]: https://www.npmjs.com/package/remark-mdx
[size-badge]: https://img.shields.io/bundlephobia/minzip/remark-mdx.svg
[size]: https://bundlephobia.com/result?p=remark-mdx
[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg
[backers-badge]: https://opencollective.com/unified/backers/badge.svg
[collective]: https://opencollective.com/unified
[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg
[chat]: https://github.com/mdx-js/mdx/discussions
[npm]: https://docs.npmjs.com/cli/install
[contributing]: https://mdxjs.com/contributing
[support]: https://mdxjs.com/support
[coc]: https://github.com/mdx-js/.github/blob/master/code-of-conduct.md
[license]: license
[author]: https://wooorm.com
[remark]: https://github.com/remarkjs/remark
[xss]: https://en.wikipedia.org/wiki/Cross-site_scripting
[rehype]: https://github.com/rehypejs/rehype
[hast]: https://github.com/syntax-tree/hast
[mdxjs]: https://mdxjs.com

View File

@ -929,16 +929,10 @@
"cooked": "\nHere is a template literal\n\nwith an empty line\n "
},
"tail": true,
"range": [
527,
577
]
"range": [527, 577]
}
],
"range": [
526,
578
]
"range": [526, 578]
},
"start": 526,
"end": 578,
@ -952,10 +946,7 @@
"column": 61
}
},
"range": [
526,
578
]
"range": [526, 578]
}
],
"sourceType": "module",
@ -970,10 +961,7 @@
"column": 61
}
},
"range": [
526,
578
]
"range": [526, 578]
}
}
}
@ -1060,10 +1048,7 @@
"column": 17
}
},
"range": [
596,
601
]
"range": [596, 601]
},
"property": {
"type": "Identifier",
@ -1080,10 +1065,7 @@
"column": 22
}
},
"range": [
602,
606
]
"range": [602, 606]
},
"computed": false,
"optional": false,
@ -1097,10 +1079,7 @@
"column": 22
}
},
"range": [
596,
606
]
"range": [596, 606]
},
"start": 596,
"end": 606,
@ -1114,10 +1093,7 @@
"column": 22
}
},
"range": [
596,
606
]
"range": [596, 606]
}
],
"sourceType": "module",
@ -1132,10 +1108,7 @@
"column": 22
}
},
"range": [
596,
606
]
"range": [596, 606]
}
}
}
@ -1286,10 +1259,7 @@
"column": 11
}
},
"range": [
654,
656
]
"range": [654, 656]
},
"selfClosing": false,
"loc": {
@ -1302,10 +1272,7 @@
"column": 12
}
},
"range": [
653,
657
]
"range": [653, 657]
},
"closingElement": {
"type": "JSXClosingElement",
@ -1326,10 +1293,7 @@
"column": 21
}
},
"range": [
664,
666
]
"range": [664, 666]
},
"loc": {
"start": {
@ -1341,10 +1305,7 @@
"column": 22
}
},
"range": [
662,
667
]
"range": [662, 667]
},
"children": [
{
@ -1371,10 +1332,7 @@
"column": 14
}
},
"range": [
658,
659
]
"range": [658, 659]
},
"operator": "+",
"right": {
@ -1393,10 +1351,7 @@
"column": 16
}
},
"range": [
660,
661
]
"range": [660, 661]
},
"loc": {
"start": {
@ -1408,10 +1363,7 @@
"column": 16
}
},
"range": [
658,
661
]
"range": [658, 661]
},
"loc": {
"start": {
@ -1423,10 +1375,7 @@
"column": 17
}
},
"range": [
657,
662
]
"range": [657, 662]
}
],
"loc": {
@ -1439,10 +1388,7 @@
"column": 22
}
},
"range": [
653,
667
]
"range": [653, 667]
},
"start": 648,
"end": 670,
@ -1456,10 +1402,7 @@
"column": 25
}
},
"range": [
648,
670
]
"range": [648, 670]
}
],
"sourceType": "module",
@ -1474,10 +1417,7 @@
"column": 25
}
},
"range": [
648,
670
]
"range": [648, 670]
}
}
}

View File

@ -302,10 +302,7 @@
"column": 47
}
},
"range": [
177,
223
]
"range": [177, 223]
}
],
"loc": {
@ -318,10 +315,7 @@
"column": 47
}
},
"range": [
177,
223
]
"range": [177, 223]
}
}
},

View File

@ -395,10 +395,7 @@
"column": 24
}
},
"range": [
266,
282
]
"range": [266, 282]
},
"arguments": [
{
@ -416,10 +413,7 @@
"column": 29
}
},
"range": [
283,
287
]
"range": [283, 287]
}
],
"optional": false,
@ -433,10 +427,7 @@
"column": 30
}
},
"range": [
266,
288
]
"range": [266, 288]
},
"consequent": {
"type": "JSXElement",
@ -466,10 +457,7 @@
"column": 50
}
},
"range": [
303,
308
]
"range": [303, 308]
},
"value": {
"type": "JSXExpressionContainer",
@ -491,10 +479,7 @@
"column": 57
}
},
"range": [
310,
315
]
"range": [310, 315]
},
"loc": {
"start": {
@ -506,10 +491,7 @@
"column": 58
}
},
"range": [
309,
316
]
"range": [309, 316]
},
"loc": {
"start": {
@ -521,10 +503,7 @@
"column": 58
}
},
"range": [
303,
316
]
"range": [303, 316]
}
],
"name": {
@ -542,10 +521,7 @@
"column": 44
}
},
"range": [
296,
302
]
"range": [296, 302]
},
"selfClosing": false,
"loc": {
@ -558,10 +534,7 @@
"column": 59
}
},
"range": [
295,
317
]
"range": [295, 317]
},
"closingElement": {
"type": "JSXClosingElement",
@ -582,10 +555,7 @@
"column": 69
}
},
"range": [
321,
327
]
"range": [321, 327]
},
"loc": {
"start": {
@ -597,10 +567,7 @@
"column": 70
}
},
"range": [
319,
328
]
"range": [319, 328]
},
"children": [
{
@ -619,10 +586,7 @@
"column": 61
}
},
"range": [
317,
319
]
"range": [317, 319]
}
],
"loc": {
@ -635,10 +599,7 @@
"column": 70
}
},
"range": [
295,
328
]
"range": [295, 328]
},
"alternate": {
"type": "JSXElement",
@ -668,10 +629,7 @@
"column": 81
}
},
"range": [
336,
339
]
"range": [336, 339]
},
"property": {
"type": "JSXIdentifier",
@ -688,10 +646,7 @@
"column": 89
}
},
"range": [
340,
347
]
"range": [340, 347]
},
"loc": {
"start": {
@ -703,10 +658,7 @@
"column": 89
}
},
"range": [
336,
347
]
"range": [336, 347]
},
"selfClosing": false,
"loc": {
@ -719,10 +671,7 @@
"column": 90
}
},
"range": [
335,
348
]
"range": [335, 348]
},
"closingElement": {
"type": "JSXClosingElement",
@ -747,10 +696,7 @@
"column": 120
}
},
"range": [
375,
378
]
"range": [375, 378]
},
"property": {
"type": "JSXIdentifier",
@ -767,10 +713,7 @@
"column": 128
}
},
"range": [
379,
386
]
"range": [379, 386]
},
"loc": {
"start": {
@ -782,10 +725,7 @@
"column": 128
}
},
"range": [
375,
386
]
"range": [375, 386]
},
"loc": {
"start": {
@ -797,10 +737,7 @@
"column": 129
}
},
"range": [
373,
387
]
"range": [373, 387]
},
"children": [
{
@ -819,10 +756,7 @@
"column": 115
}
},
"range": [
348,
373
]
"range": [348, 373]
}
],
"loc": {
@ -835,10 +769,7 @@
"column": 129
}
},
"range": [
335,
387
]
"range": [335, 387]
},
"loc": {
"start": {
@ -850,10 +781,7 @@
"column": 129
}
},
"range": [
266,
387
]
"range": [266, 387]
},
"start": 261,
"end": 390,
@ -867,10 +795,7 @@
"column": 132
}
},
"range": [
261,
390
]
"range": [261, 390]
}
],
"sourceType": "module",
@ -885,10 +810,7 @@
"column": 132
}
},
"range": [
261,
390
]
"range": [261, 390]
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -122,16 +122,10 @@
"cooked": "\n // Blank line in attribute\n\n // …expression.\n"
},
"tail": true,
"range": [
65,
114
]
"range": [65, 114]
}
],
"range": [
64,
115
]
"range": [64, 115]
},
"start": 64,
"end": 115,
@ -145,10 +139,7 @@
"column": 57
}
},
"range": [
64,
115
]
"range": [64, 115]
}
],
"sourceType": "module",
@ -163,10 +154,7 @@
"column": 57
}
},
"range": [
64,
115
]
"range": [64, 115]
}
}
}
@ -285,10 +273,7 @@
}
},
"name": "z",
"range": [
159,
160
]
"range": [159, 160]
},
"value": {
"type": "Literal",
@ -306,22 +291,13 @@
},
"value": true,
"raw": "true",
"range": [
162,
166
]
"range": [162, 166]
},
"kind": "init",
"range": [
159,
166
]
"range": [159, 166]
}
],
"range": [
158,
167
]
"range": [158, 167]
},
"start": 158,
"end": 167,
@ -335,10 +311,7 @@
"column": 40
}
},
"range": [
158,
167
]
"range": [158, 167]
}
],
"sourceType": "module",
@ -353,10 +326,7 @@
"column": 40
}
},
"range": [
158,
167
]
"range": [158, 167]
}
}
}
@ -483,21 +453,12 @@
}
},
"name": "d",
"range": [
214,
215
]
"range": [214, 215]
},
"range": [
211,
215
]
"range": [211, 215]
}
],
"range": [
201,
215
]
"range": [201, 215]
},
"start": 201,
"end": 215,
@ -511,10 +472,7 @@
"column": 18
}
},
"range": [
201,
215
]
"range": [201, 215]
}
],
"sourceType": "module",
@ -534,10 +492,7 @@
"column": 14
}
},
"range": [
201,
211
]
"range": [201, 211]
}
],
"loc": {
@ -550,10 +505,7 @@
"column": 18
}
},
"range": [
201,
215
]
"range": [201, 215]
}
}
}
@ -697,10 +649,7 @@
}
},
"name": "x",
"range": [
248,
249
]
"range": [248, 249]
},
"value": {
"type": "Literal",
@ -718,16 +667,10 @@
},
"value": "1",
"raw": "'1'",
"range": [
251,
254
]
"range": [251, 254]
},
"kind": "init",
"range": [
248,
254
]
"range": [248, 254]
},
{
"type": "Property",
@ -761,10 +704,7 @@
}
},
"name": "z",
"range": [
256,
257
]
"range": [256, 257]
},
"value": {
"type": "Literal",
@ -782,33 +722,18 @@
},
"value": "zulu",
"raw": "\"zulu\"",
"range": [
259,
265
]
"range": [259, 265]
},
"kind": "init",
"range": [
256,
265
]
"range": [256, 265]
}
],
"range": [
247,
266
]
"range": [247, 266]
},
"range": [
244,
266
]
"range": [244, 266]
}
],
"range": [
244,
266
]
"range": [244, 266]
},
"start": 244,
"end": 266,
@ -822,10 +747,7 @@
"column": 39
}
},
"range": [
244,
266
]
"range": [244, 266]
}
],
"sourceType": "module",
@ -840,10 +762,7 @@
"column": 39
}
},
"range": [
244,
266
]
"range": [244, 266]
}
}
}
@ -986,10 +905,7 @@
"column": 8
}
},
"range": [
302,
306
]
"range": [302, 306]
},
"property": {
"type": "Identifier",
@ -1006,10 +922,7 @@
"column": 11
}
},
"range": [
307,
309
]
"range": [307, 309]
},
"computed": false,
"optional": false,
@ -1023,10 +936,7 @@
"column": 11
}
},
"range": [
302,
309
]
"range": [302, 309]
},
"start": 299,
"end": 310,
@ -1040,10 +950,7 @@
"column": 12
}
},
"range": [
299,
310
]
"range": [299, 310]
}
],
"sourceType": "module",
@ -1058,10 +965,7 @@
"column": 12
}
},
"range": [
299,
310
]
"range": [299, 310]
}
}
},
@ -1153,10 +1057,7 @@
"column": 16
}
},
"range": [
335,
336
]
"range": [335, 336]
},
"value": {
"type": "BinaryExpression",
@ -1178,10 +1079,7 @@
"column": 19
}
},
"range": [
338,
339
]
"range": [338, 339]
},
"operator": "+",
"right": {
@ -1200,10 +1098,7 @@
"column": 23
}
},
"range": [
342,
343
]
"range": [342, 343]
},
"loc": {
"start": {
@ -1215,10 +1110,7 @@
"column": 23
}
},
"range": [
338,
343
]
"range": [338, 343]
},
"kind": "init",
"loc": {
@ -1231,10 +1123,7 @@
"column": 23
}
},
"range": [
335,
343
]
"range": [335, 343]
}
],
"loc": {
@ -1247,10 +1136,7 @@
"column": 24
}
},
"range": [
334,
344
]
"range": [334, 344]
},
"property": {
"type": "Literal",
@ -1268,10 +1154,7 @@
"column": 28
}
},
"range": [
345,
348
]
"range": [345, 348]
},
"computed": true,
"optional": false,
@ -1285,10 +1168,7 @@
"column": 29
}
},
"range": [
334,
349
]
"range": [334, 349]
},
"start": 334,
"end": 349,
@ -1302,10 +1182,7 @@
"column": 29
}
},
"range": [
334,
349
]
"range": [334, 349]
}
],
"sourceType": "module",
@ -1320,10 +1197,7 @@
"column": 29
}
},
"range": [
334,
349
]
"range": [334, 349]
}
}
},
@ -1439,10 +1313,7 @@
"column": 9
}
},
"range": [
376,
377
]
"range": [376, 377]
},
"operator": "+",
"right": {
@ -1461,10 +1332,7 @@
"column": 13
}
},
"range": [
380,
381
]
"range": [380, 381]
},
"loc": {
"start": {
@ -1476,10 +1344,7 @@
"column": 13
}
},
"range": [
376,
381
]
"range": [376, 381]
},
"start": 371,
"end": 384,
@ -1493,10 +1358,7 @@
"column": 16
}
},
"range": [
371,
384
]
"range": [371, 384]
}
],
"sourceType": "module",
@ -1511,10 +1373,7 @@
"column": 16
}
},
"range": [
371,
384
]
"range": [371, 384]
}
}
}
@ -1641,10 +1500,7 @@
"column": 18
}
},
"range": [
416,
417
]
"range": [416, 417]
},
"value": {
"type": "BinaryExpression",
@ -1666,10 +1522,7 @@
"column": 21
}
},
"range": [
419,
420
]
"range": [419, 420]
},
"operator": "+",
"right": {
@ -1688,10 +1541,7 @@
"column": 25
}
},
"range": [
423,
424
]
"range": [423, 424]
},
"loc": {
"start": {
@ -1703,10 +1553,7 @@
"column": 25
}
},
"range": [
419,
424
]
"range": [419, 424]
},
"kind": "init",
"loc": {
@ -1719,10 +1566,7 @@
"column": 25
}
},
"range": [
416,
424
]
"range": [416, 424]
}
],
"loc": {
@ -1735,10 +1579,7 @@
"column": 26
}
},
"range": [
415,
425
]
"range": [415, 425]
},
"property": {
"type": "Literal",
@ -1756,10 +1597,7 @@
"column": 30
}
},
"range": [
426,
429
]
"range": [426, 429]
},
"computed": true,
"optional": false,
@ -1773,10 +1611,7 @@
"column": 31
}
},
"range": [
415,
430
]
"range": [415, 430]
},
"start": 415,
"end": 430,
@ -1790,10 +1625,7 @@
"column": 31
}
},
"range": [
415,
430
]
"range": [415, 430]
}
],
"sourceType": "module",
@ -1808,10 +1640,7 @@
"column": 31
}
},
"range": [
415,
430
]
"range": [415, 430]
}
}
}

View File

@ -218,10 +218,7 @@
},
"value": "echo",
"raw": "\"echo\"",
"range": [
127,
133
]
"range": [127, 133]
},
"start": 127,
"end": 133,
@ -235,10 +232,7 @@
"column": 40
}
},
"range": [
127,
133
]
"range": [127, 133]
}
],
"sourceType": "module",
@ -253,10 +247,7 @@
"column": 40
}
},
"range": [
127,
133
]
"range": [127, 133]
}
}
}
@ -316,21 +307,12 @@
}
},
"name": "props",
"range": [
139,
144
]
"range": [139, 144]
},
"range": [
136,
144
]
"range": [136, 144]
}
],
"range": [
136,
144
]
"range": [136, 144]
},
"start": 136,
"end": 144,
@ -344,10 +326,7 @@
"column": 51
}
},
"range": [
136,
144
]
"range": [136, 144]
}
],
"sourceType": "module",
@ -362,10 +341,7 @@
"column": 51
}
},
"range": [
136,
144
]
"range": [136, 144]
}
}
}
@ -533,10 +509,7 @@
},
"value": "echo",
"raw": "\"echo\"",
"range": [
250,
256
]
"range": [250, 256]
},
"start": 250,
"end": 256,
@ -550,10 +523,7 @@
"column": 40
}
},
"range": [
250,
256
]
"range": [250, 256]
}
],
"sourceType": "module",
@ -568,10 +538,7 @@
"column": 40
}
},
"range": [
250,
256
]
"range": [250, 256]
}
}
}
@ -631,21 +598,12 @@
}
},
"name": "props",
"range": [
262,
267
]
"range": [262, 267]
},
"range": [
259,
267
]
"range": [259, 267]
}
],
"range": [
259,
267
]
"range": [259, 267]
},
"start": 259,
"end": 267,
@ -659,10 +617,7 @@
"column": 51
}
},
"range": [
259,
267
]
"range": [259, 267]
}
],
"sourceType": "module",
@ -677,10 +632,7 @@
"column": 51
}
},
"range": [
259,
267
]
"range": [259, 267]
}
}
}
@ -953,10 +905,7 @@
},
"value": "echo",
"raw": "\"echo\"",
"range": [
408,
414
]
"range": [408, 414]
},
"start": 408,
"end": 414,
@ -970,10 +919,7 @@
"column": 40
}
},
"range": [
408,
414
]
"range": [408, 414]
}
],
"sourceType": "module",
@ -988,10 +934,7 @@
"column": 40
}
},
"range": [
408,
414
]
"range": [408, 414]
}
}
}
@ -1051,21 +994,12 @@
}
},
"name": "props",
"range": [
420,
425
]
"range": [420, 425]
},
"range": [
417,
425
]
"range": [417, 425]
}
],
"range": [
417,
425
]
"range": [417, 425]
},
"start": 417,
"end": 425,
@ -1079,10 +1013,7 @@
"column": 51
}
},
"range": [
417,
425
]
"range": [417, 425]
}
],
"sourceType": "module",
@ -1097,10 +1028,7 @@
"column": 51
}
},
"range": [
417,
425
]
"range": [417, 425]
}
}
}
@ -1551,10 +1479,7 @@
},
"value": "echo",
"raw": "\"echo\"",
"range": [
630,
636
]
"range": [630, 636]
},
"start": 630,
"end": 636,
@ -1568,10 +1493,7 @@
"column": 40
}
},
"range": [
630,
636
]
"range": [630, 636]
}
],
"sourceType": "module",
@ -1586,10 +1508,7 @@
"column": 40
}
},
"range": [
630,
636
]
"range": [630, 636]
}
}
}
@ -1649,21 +1568,12 @@
}
},
"name": "props",
"range": [
642,
647
]
"range": [642, 647]
},
"range": [
639,
647
]
"range": [639, 647]
}
],
"range": [
639,
647
]
"range": [639, 647]
},
"start": 639,
"end": 647,
@ -1677,10 +1587,7 @@
"column": 51
}
},
"range": [
639,
647
]
"range": [639, 647]
}
],
"sourceType": "module",
@ -1695,10 +1602,7 @@
"column": 51
}
},
"range": [
639,
647
]
"range": [639, 647]
}
}
}
@ -2086,10 +1990,7 @@
},
"value": "echo",
"raw": "\"echo\"",
"range": [
789,
795
]
"range": [789, 795]
},
"start": 789,
"end": 795,
@ -2103,10 +2004,7 @@
"column": 40
}
},
"range": [
789,
795
]
"range": [789, 795]
}
],
"sourceType": "module",
@ -2121,10 +2019,7 @@
"column": 40
}
},
"range": [
789,
795
]
"range": [789, 795]
}
}
}
@ -2184,21 +2079,12 @@
}
},
"name": "props",
"range": [
801,
806
]
"range": [801, 806]
},
"range": [
798,
806
]
"range": [798, 806]
}
],
"range": [
798,
806
]
"range": [798, 806]
},
"start": 798,
"end": 806,
@ -2212,10 +2098,7 @@
"column": 51
}
},
"range": [
798,
806
]
"range": [798, 806]
}
],
"sourceType": "module",
@ -2230,10 +2113,7 @@
"column": 51
}
},
"range": [
798,
806
]
"range": [798, 806]
}
}
}
@ -2533,10 +2413,7 @@
},
"value": "echo",
"raw": "\"echo\"",
"range": [
916,
922
]
"range": [916, 922]
},
"start": 916,
"end": 922,
@ -2550,10 +2427,7 @@
"column": 40
}
},
"range": [
916,
922
]
"range": [916, 922]
}
],
"sourceType": "module",
@ -2568,10 +2442,7 @@
"column": 40
}
},
"range": [
916,
922
]
"range": [916, 922]
}
}
}
@ -2631,21 +2502,12 @@
}
},
"name": "props",
"range": [
928,
933
]
"range": [928, 933]
},
"range": [
925,
933
]
"range": [925, 933]
}
],
"range": [
925,
933
]
"range": [925, 933]
},
"start": 925,
"end": 933,
@ -2659,10 +2521,7 @@
"column": 51
}
},
"range": [
925,
933
]
"range": [925, 933]
}
],
"sourceType": "module",
@ -2677,10 +2536,7 @@
"column": 51
}
},
"range": [
925,
933
]
"range": [925, 933]
}
}
}
@ -3082,10 +2938,7 @@
},
"value": "echo",
"raw": "\"echo\"",
"range": [
1078,
1084
]
"range": [1078, 1084]
},
"start": 1078,
"end": 1084,
@ -3099,10 +2952,7 @@
"column": 40
}
},
"range": [
1078,
1084
]
"range": [1078, 1084]
}
],
"sourceType": "module",
@ -3117,10 +2967,7 @@
"column": 40
}
},
"range": [
1078,
1084
]
"range": [1078, 1084]
}
}
}
@ -3180,21 +3027,12 @@
}
},
"name": "props",
"range": [
1090,
1095
]
"range": [1090, 1095]
},
"range": [
1087,
1095
]
"range": [1087, 1095]
}
],
"range": [
1087,
1095
]
"range": [1087, 1095]
},
"start": 1087,
"end": 1095,
@ -3208,10 +3046,7 @@
"column": 51
}
},
"range": [
1087,
1095
]
"range": [1087, 1095]
}
],
"sourceType": "module",
@ -3226,10 +3061,7 @@
"column": 51
}
},
"range": [
1087,
1095
]
"range": [1087, 1095]
}
}
}
@ -3812,10 +3644,7 @@
},
"value": "echo",
"raw": "\"echo\"",
"range": [
1310,
1316
]
"range": [1310, 1316]
},
"start": 1310,
"end": 1316,
@ -3829,10 +3658,7 @@
"column": 40
}
},
"range": [
1310,
1316
]
"range": [1310, 1316]
}
],
"sourceType": "module",
@ -3847,10 +3673,7 @@
"column": 40
}
},
"range": [
1310,
1316
]
"range": [1310, 1316]
}
}
}
@ -3910,21 +3733,12 @@
}
},
"name": "props",
"range": [
1322,
1327
]
"range": [1322, 1327]
},
"range": [
1319,
1327
]
"range": [1319, 1327]
}
],
"range": [
1319,
1327
]
"range": [1319, 1327]
},
"start": 1319,
"end": 1327,
@ -3938,10 +3752,7 @@
"column": 51
}
},
"range": [
1319,
1327
]
"range": [1319, 1327]
}
],
"sourceType": "module",
@ -3956,10 +3767,7 @@
"column": 51
}
},
"range": [
1319,
1327
]
"range": [1319, 1327]
}
}
}

View File

@ -288,10 +288,7 @@
"column": 44
}
},
"range": [
180,
185
]
"range": [180, 185]
},
"property": {
"type": "Identifier",
@ -308,10 +305,7 @@
"column": 49
}
},
"range": [
186,
190
]
"range": [186, 190]
},
"computed": false,
"optional": false,
@ -325,10 +319,7 @@
"column": 49
}
},
"range": [
180,
190
]
"range": [180, 190]
},
"start": 180,
"end": 190,
@ -342,10 +333,7 @@
"column": 49
}
},
"range": [
180,
190
]
"range": [180, 190]
}
],
"sourceType": "module",
@ -360,10 +348,7 @@
"column": 49
}
},
"range": [
180,
190
]
"range": [180, 190]
}
}
}
@ -643,10 +628,7 @@
"column": 22
}
},
"range": [
263,
268
]
"range": [263, 268]
},
"property": {
"type": "Identifier",
@ -663,10 +645,7 @@
"column": 27
}
},
"range": [
269,
273
]
"range": [269, 273]
},
"computed": false,
"optional": false,
@ -680,10 +659,7 @@
"column": 27
}
},
"range": [
263,
273
]
"range": [263, 273]
},
"start": 263,
"end": 273,
@ -697,10 +673,7 @@
"column": 27
}
},
"range": [
263,
273
]
"range": [263, 273]
}
],
"sourceType": "module",
@ -715,10 +688,7 @@
"column": 27
}
},
"range": [
263,
273
]
"range": [263, 273]
}
}
}
@ -821,10 +791,7 @@
"column": 35
}
},
"range": [
317,
322
]
"range": [317, 322]
},
"property": {
"type": "Identifier",
@ -841,10 +808,7 @@
"column": 41
}
},
"range": [
323,
328
]
"range": [323, 328]
},
"computed": false,
"optional": false,
@ -858,10 +822,7 @@
"column": 41
}
},
"range": [
317,
328
]
"range": [317, 328]
},
"start": 317,
"end": 328,
@ -875,10 +836,7 @@
"column": 41
}
},
"range": [
317,
328
]
"range": [317, 328]
}
],
"sourceType": "module",
@ -893,10 +851,7 @@
"column": 41
}
},
"range": [
317,
328
]
"range": [317, 328]
}
}
}
@ -1040,10 +995,7 @@
"column": 22
}
},
"range": [
367,
372
]
"range": [367, 372]
},
"property": {
"type": "Identifier",
@ -1060,10 +1012,7 @@
"column": 27
}
},
"range": [
373,
377
]
"range": [373, 377]
},
"computed": false,
"optional": false,
@ -1077,10 +1026,7 @@
"column": 27
}
},
"range": [
367,
377
]
"range": [367, 377]
},
"start": 367,
"end": 377,
@ -1094,10 +1040,7 @@
"column": 27
}
},
"range": [
367,
377
]
"range": [367, 377]
}
],
"sourceType": "module",
@ -1112,10 +1055,7 @@
"column": 27
}
},
"range": [
367,
377
]
"range": [367, 377]
}
}
}
@ -1466,10 +1406,7 @@
"column": 7
}
},
"range": [
627,
631
]
"range": [627, 631]
}
],
"body": {
@ -1501,10 +1438,7 @@
"column": 31
}
},
"range": [
647,
655
]
"range": [647, 655]
},
"init": {
"type": "CallExpression",
@ -1525,10 +1459,7 @@
"column": 41
}
},
"range": [
658,
665
]
"range": [658, 665]
},
"arguments": [
{
@ -1546,10 +1477,7 @@
"column": 46
}
},
"range": [
666,
670
]
"range": [666, 670]
}
],
"optional": false,
@ -1563,10 +1491,7 @@
"column": 47
}
},
"range": [
658,
671
]
"range": [658, 671]
},
"loc": {
"start": {
@ -1578,10 +1503,7 @@
"column": 47
}
},
"range": [
647,
671
]
"range": [647, 671]
}
],
"kind": "const",
@ -1595,10 +1517,7 @@
"column": 47
}
},
"range": [
641,
671
]
"range": [641, 671]
},
{
"type": "ReturnStatement",
@ -1628,10 +1547,7 @@
"column": 63
}
},
"range": [
685,
687
]
"range": [685, 687]
},
"selfClosing": false,
"loc": {
@ -1644,10 +1560,7 @@
"column": 64
}
},
"range": [
684,
688
]
"range": [684, 688]
},
"closingElement": {
"type": "JSXClosingElement",
@ -1668,10 +1581,7 @@
"column": 78
}
},
"range": [
700,
702
]
"range": [700, 702]
},
"loc": {
"start": {
@ -1683,10 +1593,7 @@
"column": 79
}
},
"range": [
698,
703
]
"range": [698, 703]
},
"children": [
{
@ -1708,10 +1615,7 @@
"column": 73
}
},
"range": [
689,
697
]
"range": [689, 697]
},
"loc": {
"start": {
@ -1723,10 +1627,7 @@
"column": 74
}
},
"range": [
688,
698
]
"range": [688, 698]
}
],
"loc": {
@ -1739,10 +1640,7 @@
"column": 79
}
},
"range": [
684,
703
]
"range": [684, 703]
},
"loc": {
"start": {
@ -1754,10 +1652,7 @@
"column": 79
}
},
"range": [
677,
703
]
"range": [677, 703]
}
],
"loc": {
@ -1770,10 +1665,7 @@
"column": 83
}
},
"range": [
635,
707
]
"range": [635, 707]
},
"loc": {
"start": {
@ -1785,10 +1677,7 @@
"column": 83
}
},
"range": [
627,
707
]
"range": [627, 707]
},
"start": 627,
"end": 707,
@ -1802,10 +1691,7 @@
"column": 83
}
},
"range": [
627,
707
]
"range": [627, 707]
}
],
"sourceType": "module",
@ -1820,10 +1706,7 @@
"column": 83
}
},
"range": [
627,
707
]
"range": [627, 707]
}
}
}
@ -1943,16 +1826,10 @@
"cooked": "\n Here's a template string\n\n with empty lines\n "
},
"tail": true,
"range": [
779,
833
]
"range": [779, 833]
}
],
"range": [
778,
834
]
"range": [778, 834]
},
"start": 778,
"end": 834,
@ -1966,10 +1843,7 @@
"column": 68
}
},
"range": [
778,
834
]
"range": [778, 834]
}
],
"sourceType": "module",
@ -1984,10 +1858,7 @@
"column": 68
}
},
"range": [
778,
834
]
"range": [778, 834]
}
}
}
@ -2540,10 +2411,7 @@
"column": 22
}
},
"range": [
1107,
1112
]
"range": [1107, 1112]
},
"property": {
"type": "Identifier",
@ -2560,10 +2428,7 @@
"column": 27
}
},
"range": [
1113,
1117
]
"range": [1113, 1117]
},
"computed": false,
"optional": false,
@ -2577,10 +2442,7 @@
"column": 27
}
},
"range": [
1107,
1117
]
"range": [1107, 1117]
},
"start": 1107,
"end": 1117,
@ -2594,10 +2456,7 @@
"column": 27
}
},
"range": [
1107,
1117
]
"range": [1107, 1117]
}
],
"sourceType": "module",
@ -2612,10 +2471,7 @@
"column": 27
}
},
"range": [
1107,
1117
]
"range": [1107, 1117]
}
}
}
@ -2709,10 +2565,7 @@
"column": 19
}
},
"range": [
1137,
1142
]
"range": [1137, 1142]
},
"property": {
"type": "Identifier",
@ -2729,10 +2582,7 @@
"column": 24
}
},
"range": [
1143,
1147
]
"range": [1143, 1147]
},
"computed": false,
"optional": false,
@ -2746,10 +2596,7 @@
"column": 24
}
},
"range": [
1137,
1147
]
"range": [1137, 1147]
},
"start": 1137,
"end": 1147,
@ -2763,10 +2610,7 @@
"column": 24
}
},
"range": [
1137,
1147
]
"range": [1137, 1147]
}
],
"sourceType": "module",
@ -2781,10 +2625,7 @@
"column": 24
}
},
"range": [
1137,
1147
]
"range": [1137, 1147]
}
}
}

View File

@ -288,10 +288,7 @@
"column": 36
}
},
"range": [
138,
139
]
"range": [138, 139]
},
"operator": "+",
"right": {
@ -310,10 +307,7 @@
"column": 40
}
},
"range": [
142,
143
]
"range": [142, 143]
},
"loc": {
"start": {
@ -325,10 +319,7 @@
"column": 40
}
},
"range": [
138,
143
]
"range": [138, 143]
},
"start": 138,
"end": 143,
@ -342,10 +333,7 @@
"column": 40
}
},
"range": [
138,
143
]
"range": [138, 143]
}
],
"sourceType": "module",
@ -360,10 +348,7 @@
"column": 40
}
},
"range": [
138,
143
]
"range": [138, 143]
}
}
},
@ -888,10 +873,7 @@
"column": 9
}
},
"range": [
306,
307
]
"range": [306, 307]
},
"operator": "+",
"right": {
@ -910,10 +892,7 @@
"column": 13
}
},
"range": [
310,
311
]
"range": [310, 311]
},
"loc": {
"start": {
@ -925,10 +904,7 @@
"column": 13
}
},
"range": [
306,
311
]
"range": [306, 311]
},
"start": 306,
"end": 311,
@ -942,10 +918,7 @@
"column": 13
}
},
"range": [
306,
311
]
"range": [306, 311]
}
],
"sourceType": "module",
@ -960,10 +933,7 @@
"column": 13
}
},
"range": [
306,
311
]
"range": [306, 311]
}
}
}
@ -2025,10 +1995,7 @@
"column": 38
}
},
"range": [
877,
889
]
"range": [877, 889]
},
"start": 877,
"end": 889,
@ -2042,10 +2009,7 @@
"column": 38
}
},
"range": [
877,
889
]
"range": [877, 889]
}
],
"sourceType": "module",
@ -2060,10 +2024,7 @@
"column": 38
}
},
"range": [
877,
889
]
"range": [877, 889]
}
}
}
@ -2094,8 +2055,8 @@
"offset": 897
}
},
"identifier": "x",
"label": "x",
"identifier": "x",
"referenceType": "full"
},
{

View File

@ -100,10 +100,7 @@
"column": 33
}
},
"range": [
32,
33
]
"range": [32, 33]
},
"operator": "+",
"right": {
@ -122,10 +119,7 @@
"column": 37
}
},
"range": [
36,
37
]
"range": [36, 37]
},
"loc": {
"start": {
@ -137,10 +131,7 @@
"column": 37
}
},
"range": [
32,
37
]
"range": [32, 37]
},
"start": 32,
"end": 37,
@ -154,10 +145,7 @@
"column": 37
}
},
"range": [
32,
37
]
"range": [32, 37]
}
],
"sourceType": "module",
@ -172,10 +160,7 @@
"column": 37
}
},
"range": [
32,
37
]
"range": [32, 37]
}
}
}
@ -389,10 +374,7 @@
"column": 44
}
},
"range": [
113,
123
]
"range": [113, 123]
},
"arguments": [
{
@ -410,10 +392,7 @@
"column": 49
}
},
"range": [
124,
128
]
"range": [124, 128]
}
],
"optional": false,
@ -427,10 +406,7 @@
"column": 50
}
},
"range": [
113,
129
]
"range": [113, 129]
},
"start": 113,
"end": 129,
@ -444,10 +420,7 @@
"column": 50
}
},
"range": [
113,
129
]
"range": [113, 129]
}
],
"sourceType": "module",
@ -462,10 +435,7 @@
"column": 50
}
},
"range": [
113,
129
]
"range": [113, 129]
}
}
},
@ -652,10 +622,7 @@
}
},
"name": "user",
"range": [
217,
221
]
"range": [217, 221]
},
"property": {
"type": "Identifier",
@ -672,17 +639,11 @@
}
},
"name": "avatarUrl",
"range": [
222,
231
]
"range": [222, 231]
},
"computed": false,
"optional": false,
"range": [
217,
231
]
"range": [217, 231]
},
"start": 217,
"end": 231,
@ -696,10 +657,7 @@
"column": 53
}
},
"range": [
217,
231
]
"range": [217, 231]
}
],
"sourceType": "module",
@ -714,10 +672,7 @@
"column": 53
}
},
"range": [
217,
231
]
"range": [217, 231]
}
}
}
@ -845,21 +800,12 @@
}
},
"name": "props",
"range": [
274,
279
]
"range": [274, 279]
},
"range": [
271,
279
]
"range": [271, 279]
}
],
"range": [
271,
279
]
"range": [271, 279]
},
"start": 271,
"end": 279,
@ -873,10 +819,7 @@
"column": 37
}
},
"range": [
271,
279
]
"range": [271, 279]
}
],
"sourceType": "module",
@ -891,10 +834,7 @@
"column": 37
}
},
"range": [
271,
279
]
"range": [271, 279]
}
}
}

View File

@ -26,7 +26,10 @@ const basic = unified().use(remarkParse).use(remarkMdx)
test('parse: MDX vs. MDX.js', () => {
assert.equal(
clean(unified().use(remarkParse).use(remarkMdx).parse('{1 + /* } */ 2}').children[0]),
clean(
unified().use(remarkParse).use(remarkMdx).parse('{1 + /* } */ 2}')
.children[0]
),
u('mdxFlowExpression', {data: {estree: null}}, '1 + /* } */ 2'),
'should parse expressions in gnostic mode (default)'
)
@ -499,9 +502,7 @@ test('parse: complete', () => {
)
assert.equal(
clean(
basic.parse('Alpha <b xml :\tlang\n= "de-CH" foo:bar>charlie</b>.')
),
clean(basic.parse('Alpha <b xml :\tlang\n= "de-CH" foo:bar>charlie</b>.')),
u('root', [
u('paragraph', [
u('text', 'Alpha '),
@ -1081,7 +1082,10 @@ test('stringify', () => {
u('root', [
u(
'mdxJsxTextElement',
{name: null, attributes: [u('mdxJsxAttribute', {name: 'bravo'}, 'bravo')]},
{
name: null,
attributes: [u('mdxJsxAttribute', {name: 'bravo'}, 'bravo')]
},
[]
)
])
@ -1097,7 +1101,10 @@ test('stringify', () => {
u('root', [
u(
'mdxJsxTextElement',
{name: null, attributes: [u('mdxJsxAttribute', {name: 'br:avo'}, 'bravo')]},
{
name: null,
attributes: [u('mdxJsxAttribute', {name: 'br:avo'}, 'bravo')]
},
[]
)
])
@ -1113,7 +1120,10 @@ test('stringify', () => {
u('root', [
u(
'mdxJsxTextElement',
{name: null, attributes: [u('mdxJsxExpressionAttribute', '...props')]},
{
name: null,
attributes: [u('mdxJsxExpressionAttribute', '...props')]
},
[]
)
])
@ -1263,7 +1273,10 @@ test('stringify', () => {
u('text', 'Alpha '),
u(
'mdxJsxTextElement',
{name: 'b', attributes: [u('mdxJsxExpressionAttribute', '...props')]},
{
name: 'b',
attributes: [u('mdxJsxExpressionAttribute', '...props')]
},
[]
),
u('text', ' charlie.')
@ -1308,7 +1321,9 @@ test('stringify', () => {
basic.stringify(
u('root', [
u('paragraph', [
u('link', {url: 'https://mdxjs.com'}, [u('text', 'https://mdxjs.com')])
u('link', {url: 'https://mdxjs.com'}, [
u('text', 'https://mdxjs.com')
])
])
])
),
@ -1318,18 +1333,16 @@ test('stringify', () => {
assert.equal(
basic.stringify(
u('root', [
u('paragraph', [u('link', {url: 'https://mdxjs.com'}, [])])
])
u('root', [u('paragraph', [u('link', {url: 'https://mdxjs.com'}, [])])])
),
'[](https://mdxjs.com)\n',
'should support links w/o content'
)
assert.equal(
basic.stringify(u('root', [
u('paragraph', [u('link', {url: ''}, [u('text', '')])])
])),
basic.stringify(
u('root', [u('paragraph', [u('link', {url: ''}, [u('text', '')])])])
),
'[]()\n',
'should support links w/o url'
)
@ -1367,7 +1380,9 @@ test('stringify', () => {
u('root', [
u('paragraph', [
u('text', 'Alpha '),
u('mdxJsxTextElement', {name: null, attributes: []}, [u('text', '1 < 3')]),
u('mdxJsxTextElement', {name: null, attributes: []}, [
u('text', '1 < 3')
]),
u('text', ' bravo.')
])
])
@ -1381,7 +1396,9 @@ test('stringify', () => {
u('root', [
u('paragraph', [
u('text', 'Alpha '),
u('mdxJsxTextElement', {name: null, attributes: []}, [u('text', '1 > 3')]),
u('mdxJsxTextElement', {name: null, attributes: []}, [
u('text', '1 > 3')
]),
u('text', ' bravo.')
])
])
@ -1438,7 +1455,9 @@ test('stringify', () => {
u('root', [
u('paragraph', [
u('text', 'Alpha '),
u('mdxJsxTextElement', {name: null, attributes: []}, [u('text', '1 { 3')]),
u('mdxJsxTextElement', {name: null, attributes: []}, [
u('text', '1 { 3')
]),
u('text', ' bravo.')
])
])
@ -1452,7 +1471,9 @@ test('stringify', () => {
u('root', [
u('paragraph', [
u('text', 'Alpha '),
u('mdxJsxTextElement', {name: null, attributes: []}, [u('text', '1 } 3')]),
u('mdxJsxTextElement', {name: null, attributes: []}, [
u('text', '1 } 3')
]),
u('text', ' bravo.')
])
])
@ -1494,11 +1515,15 @@ test('fixtures', () => {
fs.readdirSync(base)
.filter(d => /\.md$/.test(d))
.forEach(name => {
const proc = unified().use(remarkParse).use(remarkStringify).use(remarkMdx)
const proc = unified()
.use(remarkParse)
.use(remarkStringify)
.use(remarkMdx)
const fpIn = path.join(base, name)
const fpExpected = fpIn.replace(/\.md$/, '.json')
const fpExpectedDoc = fpIn.replace(/\.md$/, '.out')
const input = readSync(fpIn)
input.value = String(input.value).replace(/\r\n/g, '\n')
/** @type {Root} */
const tree = JSON.parse(JSON.stringify(proc.parse(input)))
const doc = proc.stringify(tree)
@ -1513,26 +1538,24 @@ test('fixtures', () => {
expected = tree
writeSync({
path: fpExpected,
contents: JSON.stringify(expected, null, 2) + '\n'
value: JSON.stringify(expected, null, 2) + '\n'
})
}
assert.equal(tree, expected, input.stem + ' (tree)')
try {
expectedDoc = String(readSync(fpExpectedDoc))
expectedDoc = String(readSync(fpExpectedDoc)).replace(/\r\n/g, '\n')
} catch (_) {
expectedDoc = String(input)
if (expectedDoc !== doc) {
expectedDoc = doc
writeSync({path: fpExpectedDoc, contents: expectedDoc})
writeSync({path: fpExpectedDoc, value: expectedDoc})
}
}
// Windows.
expectedDoc = expectedDoc.replace(/\r\n/g, '\n')
assert.equal(doc, expectedDoc, input.stem + ' (doc)')
const reparsed = proc.parse(doc)
@ -1552,7 +1575,6 @@ function clean(tree) {
return tree
}
/**
* @param {Root|Content} tree
*/
@ -1570,7 +1592,8 @@ function cleanEstree(tree) {
node.type === 'mdxJsxAttribute' ||
node.type === 'mdxJsxAttributeValueExpression' ||
node.type === 'mdxJsxExpressionAttribute') &&
(node.data && node.data.estree)
node.data &&
node.data.estree
) {
node.data.estree = null
}
@ -1579,7 +1602,7 @@ function cleanEstree(tree) {
node.type === 'mdxJsxTextElement' ||
node.type === 'mdxJsxFlowElement'
) {
node.attributes.forEach((child) => {
node.attributes.forEach(child => {
onvisit(child)
if (child.value && typeof child.value === 'object') {
onvisit(child.value)

View File

@ -1,11 +0,0 @@
{
"presets": [
[
"@babel/env",
{
"corejs": 3,
"useBuiltIns": "usage"
}
]
]
}

View File

@ -16,7 +16,11 @@ export const MDXProvider = {
* @this {import('vue').ComponentPublicInstance}
*/
render() {
return createVNode(Fragment, null, this.$slots.default ? this.$slots.default() : [])
return createVNode(
Fragment,
null,
this.$slots.default ? this.$slots.default() : []
)
}
}

View File

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2017-2019 Compositor, Inc. and Vercel, Inc.
Copyright (c) 2017 Compositor, Inc. and Vercel, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -79,20 +79,37 @@ abide by its terms.
[MIT][] © [Compositor][] and [Vercel][]
[build-badge]: https://github.com/mdx-js/mdx/workflows/CI/badge.svg
[build]: https://github.com/mdx-js/mdx/actions
[downloads-badge]: https://img.shields.io/npm/dm/@mdx-js/vue.svg
[downloads]: https://www.npmjs.com/package/@mdx-js/vue
[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg
[backers-badge]: https://opencollective.com/unified/backers/badge.svg
[opencollective]: https://opencollective.com/unified
[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg
[chat]: https://github.com/mdx-js/mdx/discussions
[mdx]: https://mdxjs.com
[npm]: https://docs.npmjs.com/cli/install
[yarn]: https://yarnpkg.com/cli/add
[contributing]: https://mdxjs.com/contributing
[support]: https://mdxjs.com/support
[coc]: https://github.com/mdx-js/.github/blob/master/code-of-conduct.md
[mit]: license
[compositor]: https://compositor.io
[vercel]: https://vercel.com

View File

@ -19,10 +19,21 @@ import {useMDXComponents, MDXProvider} from '../index.js'
* @returns {Promise.<{default: MDXContent}>}
*/
async function evaluate(value) {
const file = await compile(value, {providerImportSource: '#', jsx: true, outputFormat: 'function-body'})
const result = await babel.transformAsync(String(file), {parserOpts: {allowReturnOutsideFunction: true}, plugins: ['@vue/babel-plugin-jsx']})
const file = await compile(value, {
providerImportSource: '#',
jsx: true,
outputFormat: 'function-body'
})
const result = await babel.transformAsync(String(file), {
parserOpts: {allowReturnOutsideFunction: true},
plugins: ['@vue/babel-plugin-jsx']
})
if (!result || !result.code) throw new Error('Whoops!')
const body = result.code.replace(/import \{(.+)\} from "vue"/, (_, /** @type {string} */ $1) => 'const {' + $1.replace(/ as /g, ': ') + '} = arguments[0].vue')
const body = result.code.replace(
/import \{(.+)\} from "vue"/,
(_, /** @type {string} */ $1) =>
'const {' + $1.replace(/ as /g, ': ') + '} = arguments[0].vue'
)
// @ts-expect-error: to do xdm (and mdx-js/mdx soon) also supports strings instead of vfiles for run.
return run(body, {vue, useMDXComponents})
}
@ -33,7 +44,9 @@ async function evaluate(value) {
* @returns {Promise<string>}
*/
async function vueToString(root, rootProps) {
const result = await serverRenderer.renderToString(vue.createSSRApp(root, rootProps))
const result = await serverRenderer.renderToString(
vue.createSSRApp(root, rootProps)
)
// Remove SSR comments used to hydrate.
return result.replace(/<!--[[\]]-->/g, '')
}
@ -60,10 +73,7 @@ test('should support Vue components defined in MDX', async () => {
'export const A = {render() { return <b>!</b> }}\n\n<A />'
)
assert.equal(
await vueToString(Content),
'<b>!</b>'
)
assert.equal(await vueToString(Content), '<b>!</b>')
})
test('should support passing `components`', async () => {
@ -92,7 +102,8 @@ test('should support `MDXProvider`', async () => {
data() {
return {components: {h1: 'h2'}}
},
template: '<MDXProvider v-bind:components="components"><Content /></MDXProvider>',
template:
'<MDXProvider v-bind:components="components"><Content /></MDXProvider>',
components: {MDXProvider, Content}
}),
'<h2>hi</h2>'

View File

@ -1,4 +1,4 @@
<!-- lint disable remark-lint-no-html -->
<!-- lint disable no-html -->
<p align="center">
<a href="https://mdxjs.com">
@ -11,7 +11,8 @@
[![Build Status][build-badge]][build]
[![Chat][chat-badge]][chat]
[MDX][website] is an authorable format that lets you seamlessly use JSX in your markdown documents.
[MDX][website] is an authorable format that lets you seamlessly use JSX in your
markdown documents.
You can import components, like interactive charts or notifications, and export
metadata.
This makes writing long-form content with components a blast.
@ -71,27 +72,27 @@ with JSX.
Implementations were often template string-based which required lots of escaping
and cumbersome syntax.
> MDX \[…] is extremely useful for using design system components to render
> markdown and weaving interactive components in with existing markdown.
> MDX \[…] is extremely useful for using design system components to render
> markdown and weaving interactive components in with existing markdown.
>
> — [@chrisbiscardi][tweet]
MDX seeks to make writing with markdown _and_ JSX simpler while being more
MDX seeks to make writing with markdown *and* JSX simpler while being more
expressive.
The possibilities are endless when you combine components (that can even be
dynamic or load data) with the simplicity of markdown for long-form content.
A nice example of this is [mdx-deck][], a great way to create slides with MDX.
- Fast
- No runtime compilation
- [Pluggable][remark-plugins]
- Element to React component mapping
- React component `import`/`export`
- Customizable layouts
- [Webpack loader](https://mdxjs.com/getting-started/webpack)
- [Parcel plugin](https://mdxjs.com/getting-started/parcel)
- [Next.js plugin](https://mdxjs.com/getting-started/next)
- [Gatsby plugin](https://mdxjs.com/getting-started/gatsby)
* Fast
* No runtime compilation
* [Pluggable][remark-plugins]
* Element to React component mapping
* React component `import`/`export`
* Customizable layouts
* [Webpack loader](https://mdxjs.com/getting-started/webpack)
* [Parcel plugin](https://mdxjs.com/getting-started/parcel)
* [Next.js plugin](https://mdxjs.com/getting-started/next)
* [Gatsby plugin](https://mdxjs.com/getting-started/gatsby)
## Sponsors
@ -142,10 +143,10 @@ Support this effort and give back by sponsoring on [OpenCollective][collective]!
## Authors
- [John Otander][john] ([@4lpine][4lpine]) [Components AI][]
- [Tim Neutkens][tim] ([@timneutkens][timneutkens]) [Vercel][]
- [Guillermo Rauch][guillermo] ([@rauchg][rauchg]) [Vercel][]
- [Brent Jackson][brent] ([@jxnblk][jxnblk]) [Gatsby](https://gatsbyjs.com)
* [John Otander][john] ([@4lpine][4lpine]) [Components AI][]
* [Tim Neutkens][tim] ([@timneutkens][timneutkens]) [Vercel][]
* [Guillermo Rauch][guillermo] ([@rauchg][rauchg]) [Vercel][]
* [Brent Jackson][brent] ([@jxnblk][jxnblk]) [Gatsby](https://gatsbyjs.com)
## Related
@ -169,28 +170,53 @@ Join us on [GH Discussions][chat]!
[MIT][] © Compositor and [Vercel][]
[collective]: https://opencollective.com/unified
[build]: https://github.com/mdx-js/mdx/actions?query=workflow%3A%22CI%22
[build-badge]: https://github.com/mdx-js/mdx/workflows/CI/badge.svg
[chat-badge]: https://img.shields.io/badge/chat-discussions-success.svg
[chat]: https://github.com/mdx-js/mdx/discussions
[intro]: https://www.youtube.com/watch?v=d2sQiI5NFAM&list=PLV5CVI1eNcJgCrPH_e6d57KRUTiDZgs0u
[tweet]: https://twitter.com/chrisbiscardi/status/1022304288326864896
[remark-plugins]: https://github.com/remarkjs/remark/blob/master/doc/plugins.md
[website]: https://mdxjs.com
[spec]: https://github.com/mdx-js/specification#related
[john]: https://johno.com
[tim]: https://github.com/timneutkens
[guillermo]: https://rauchg.com
[brent]: https://jxnblk.com
[4lpine]: https://twitter.com/4lpine
[rauchg]: https://twitter.com/rauchg
[timneutkens]: https://twitter.com/timneutkens
[jxnblk]: https://twitter.com/jxnblk
[components ai]: https://components.ai
[vercel]: https://vercel.com
[contribute]: #contribute
[contributing]: https://mdxjs.com/contributing
[support]: https://mdxjs.com/support
[coc]: https://github.com/mdx-js/.github/blob/master/code-of-conduct.md
[mdx-deck]: https://github.com/jxnblk/mdx-deck
[mit]: license

View File

@ -49,7 +49,10 @@ main().catch(error => {
})
async function main() {
fs.copyFile(new URL('404/index.html', config.output), new URL('404.html', config.output))
fs.copyFile(
new URL('404/index.html', config.output),
new URL('404.html', config.output)
)
console.log('✔ `/404/index.html` -> `/404.html`')
const css = await fs.readFile(

View File

@ -23,7 +23,9 @@ async function main() {
const files = await globby('**/*', {cwd: fileURLToPath(from)})
await pAll(
files.map(d => async () => fs.copyFile(new URL(d, from), new URL(d, config.output))),
files.map(
d => async () => fs.copyFile(new URL(d, from), new URL(d, config.output))
),
{concurrency: 6}
)

View File

@ -49,7 +49,6 @@ async function main() {
await globby('**/index.nljson', {cwd: fileURLToPath(config.output)})
).map(d => new URL(d, config.output))
await pAll(
files.map(url => async () => {
const name = url.href