mdx-js / mdx Goto Github PK
View Code? Open in Web Editor NEWMarkdown for the component era
Home Page: https://mdxjs.com
License: MIT License
Markdown for the component era
Home Page: https://mdxjs.com
License: MIT License
After some discussion with @timneutkens and @jxnblk we think it makes most sense to allow layout to be optionally specified in frontmatter.
---
title: Awesome Page
slug: /awesome
layout: ./PageLayout
team:
- jxn
- mrmrs
- johno
---
Resulting in, when layout
is defined, the result would be something similar to:
import PageLayout from './PageLayout'
// ... stuff
export default PostLayout(frontmatter)(Markdown)
Something to consider: Should a layout be a HOC or standard component?
This will be, at least temporarily, required for more complex blocks of jsx due to limitations in parsing.
This breaks:
`<test>`
Old:
<TerminalInput prefix>npm i next@latest react@latest react-dom@latest</TerminalInput>
<Caption>In addition to bumping Next.js etc...</Caption>
new:
<TerminalInput prefix>npm i next@latest react@latest react-dom@latest</TerminalInput>
<Caption>In addition to bumping Next.js etc...</Caption>
In the renderer we should be adding a key prop, we currently aren't resulting in the following error:
Warning: Each child in an array or iterator should have a unique "key" prop
If you create a file like:
# heading
hello `test`
It'll parse single quoted lines as code
blocks instead of inlineCode
as defined in the spec. I'm not sure if this is an issue with remark or mdxast ๐ค
This will add a context that provides an element to component mapping, and any other globally available components.
As an example API, this will render Heading
for the h1
element in readme.md
.
import React from 'react'
import { MarkdownProvider } from '@compositor/markdown'
import { Heading } from './ui'
import Readme from './readme.md
export default () =>
<MarkdownProvider components={{ h1: Heading }}>
<Readme />
</MarkdownProvider>
Use this to add any thoughts/criticisms/etc. to the MDX and MDXAST specs <3.
<Foo children='bar' />
Children prop is empty because the ast children
attribute is used.
p
tags<Foo>
Bar
</Foo>
Results in
<h1>
<p>Bar</p>
</h1>
<Foo>
<Bar
children={props.bar.map(b =>
<Baz key={b}>{b}</Baz>
)}
/>
</Foo>
Perhaps stuff like this is where we introduce the .jsx
code block back?
<Foo color={'pink'} />
Errors with (in next example):
Error
Error
at tokens.reduce.type (http://localhost:3000/_next/-/page/index.js:2090:19)
at Array.reduce (<anonymous>)
at parse (http://localhost:3000/_next/-/page/index.js:2084:23)
at Of.parser (http://localhost:3000/_next/-/page/index.js:823:18)
at Of.tokenize [as tokenizeBlock] (http://localhost:3000/_next/-/page/index.js:72636:18)
at Of.parse (http://localhost:3000/_next/-/page/index.js:68441:20)
at Function.parse (http://localhost:3000/_next/-/page/index.js:80537:45)
at pipelineParse (http://localhost:3000/_next/-/page/index.js:80284:16)
at wrapped (http://localhost:3000/_next/-/page/index.js:80139:19)
at next (http://localhost:3000/_next/-/page/index.js:80102:24)
```!jsx
---
foo: bar
---
<h1>{foo}</h1>
\```
It'd be nice to be able pass in additional components and props to the component scope.
import React from 'react'
import { Box } from './ui'
import Document from './doc.md'
export default () => <Document scope={{ title: 'Hello', Box }} />
# This is some markdown
That has `Box` and `title` in scope:
<Box>{title}</Box>
import fs from 'fs'
import path from 'path'
import visit from 'unist-util-visit'
import { parse } from 'remark'
import {
isTranscludable,
isRelativeFile
} from './util'
export default () => (tree, file) =>
visit(tree, 'text', (node, _i, parent) => {
if (!isRelativeFile(node.value) || !isTranscludable(node.value)) {
return
}
const index = tree.children.indexOf(parent)
if (index === -1) {
return
}
const transcludedFile = path.join(file.cwd, node.value)
let content = null
try {
content = fs.readFileSync(transcludedFile, 'utf8')
} catch (e) {
console.log(`Error transcluding ${transcludedFile}`)
}
if (content) {
tree.children = [].concat(
tree.children.slice(0, index),
parse(content).children,
tree.children.slice(index + 1)
)
}
})
Some thoughts inspired by rauchg's .mdx proposal and an iteration on formalizing c8r/markdown.
This is a <Text.span>span</Text.span>.
Specifying .jsx
as the language will render the React components.
You can also specify front matter which is passed as props to the components being rendered.
---
foo: bar
---
<Awesome>{props.foo}</Awesome>
{new Date()}
We need to be able to provide components, props,
Perhaps this can be done with a MarkdownProvider
and ScopeProvider
?
The following detauls need to be sorted out for a solid spec/implementation:
Depending on what syntax we arrive at, we will need to transform the MD AST to render the desired components.
Interesting related projects/implementations:
import Post from './posts/proposal.mdx'
export default <Post />
Ideas:
imports
as the beginning of a mdx fileSimilarly to how remark
provides a pluggable API, we should also allow plugins to be passed in.
This allows further customization down the road, and also supporting the existing remark plugin ecosystem (toc, gh integrations, etc).
Code blocks and inlined js can be run through prettier at the mdast stage and then re-output to markdown.
I suspect the same will be possible with inlined JSX as well.
Hello, <World some='prop' />
Hello, <World some="prop" />
In certain cases it'd be nice to be able to render jsx components directly, the components to be rendered need to be provided in scope
.
[[jsx]]
| <MyComponent
| with={some}
| props={here}
| />
Using code blocks with a !
postfix:
```.jsx!
<MyComponent
with={some}
props={here}
/>
\```
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.