Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider how to align with the .mdx proposal #36

Closed
johno opened this issue Feb 9, 2018 · 4 comments
Closed

Consider how to align with the .mdx proposal #36

johno opened this issue Feb 9, 2018 · 4 comments

Comments

@johno
Copy link
Member

johno commented Feb 9, 2018

Some thoughts inspired by rauchg's .mdx proposal and an iteration on formalizing c8r/markdown.

Inlining JSX

This is a <Text.span>span</Text.span>.

Code blocks

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>

Inlining JS

{new Date()}

Providing scope/element mapping

We need to be able to provide components, props,

Perhaps this can be done with a MarkdownProvider and ScopeProvider?

Implementation details

The following detauls need to be sorted out for a solid spec/implementation:

Mdast

Depending on what syntax we arrive at, we will need to transform the MD AST to render the desired components.

Interesting related projects/implementations:

Loaders for webpack/parcel

import Post from './posts/proposal.mdx'

export default <Post />

Import syntax

Ideas:

  • imports as the beginning of a mdx file
  • using front matter

Pluggable

Similarly 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).

Linting and prettier

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.

Input

Hello, <World some='prop' />

Output

Hello, <World some="prop" />
@johno
Copy link
Member Author

johno commented Feb 9, 2018

Rather than having .jsx specific syntax (assuming inline JSX support), we should have different component contexts for different syntaxes. So when you pass in your component scope you can specify components like so:

import Markdown from '@c8r/markdown'
import {
  Text,
  Heading,
  CodeBlockJSX,
  CodeBlockHTML
} from './ui'

// ...

<Markdown
  text={md}
  components={{
    p: Text.p,
    h1: Heading.h1,
    codeBlock: {
      jsx: CodeBlockJSX,
      html: CodeBlockHTML
  }}
/>

@johno
Copy link
Member Author

johno commented Feb 9, 2018

I wonder about the inlining js portion, perhaps that can be left out? Or perhaps it should be JSX {} syntax?

@johno
Copy link
Member Author

johno commented Feb 10, 2018

If a markdown document is imported with a custom babel loader, we need to consider the best way to provide a component mapping to the core library. For example, a trivial component mapping might be:

{
  a: Link,
  p: Text,
  h1: Heading,
  // ...
}

One option could be using a context provider:

import React from 'react'
import { MdProvider } from '@compositor/markdown'

import Document from './document.mdx'
import * as ui from './ui'

export default () =>
  <MdProvider components={ui}>
    <Document />
  </MdProvider>

@johno
Copy link
Member Author

johno commented Feb 11, 2018

Preliminary import, component mapping, and inlined jsx support completed ✅

@johno johno closed this as completed Feb 11, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant