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

HtmlBlock renderer for JSX #67

Closed
tauren opened this issue Mar 23, 2017 · 2 comments
Closed

HtmlBlock renderer for JSX #67

tauren opened this issue Mar 23, 2017 · 2 comments

Comments

@tauren
Copy link

tauren commented Mar 23, 2017

I would like to render markdown that contains JSX syntax, but the HtmlBlock (and probably HtmlInline) renderer fails for both standard HTML and JSX syntax. Here is an example markdown file:

<button onclick="alert('yo')">Hello</button>
<button onclick={()=>alert('Clicked')}>Click Me</button>

The first button is HTML and the second contains JSX. Here is what gets rendered by react-markdown:

<p>
  <span>
    <button onclick="alert('yo')"></button>
  </span>
  <!-- react-text: 600 -->Hello<!-- /react-text -->
  <span></span>
  <!-- react-text: 602 -->
  &lt;button onclick={()=&gt;alert('Clicked')}&gt;Click Me
  <!-- /react-text -->
  <span></span>
</p>

Both of these buttons don't render properly:

  1. The first button renders as HTML and alerts yo when clicked, but the button is empty and the text that should be inside of it is outside of it
  2. The second button doesn't render as HTML

It seems the HtmlBlock renderer may not be working properly.

How I would go about writing an HtmlBlock renderer that properly renders JSX? I need to use h() to render (I'm using the /** @jsx h */ pragma), but even an example using React.createElement() would help.

@tauren
Copy link
Author

tauren commented Mar 23, 2017

I'd like to defer the parsing issues I describe above to rexxars/commonmark-react-renderer#9 and keep the focus of this issue on building a renderer that supports JSX syntax.

I'd like to support JSX markup, including capitalized component names, className instead of class, javascript expressions as values for attributes, camelCase attributes, spread attributes, and so forth:

<Button className="primary" onclick={()=>alert('Clicked')}>Click Me</Button>
<Foo camelProp={props.foo} {...props} />

Perhaps this should already work, but with the parser not working right I'm not sure. However, I suspect a custom renderer will be necessary and am looking for advice on getting started building one.

Also, I presume that the markup above would actually be problematic, as props wouldn't be defined. But it would be interesting to figure out a way for the React component that contains the <Markdown source={} /> tag to somehow expose variables to the rendered markup. Maybe something like:

<Markdown source={source} variables={variables} />

@rexxars
Copy link
Collaborator

rexxars commented Mar 28, 2017

I'm.... skeptical to how this would work. Inline HTML is a nightmare currently, and I don't see any easy solution to fixing it. I'll leave that discussion for the other issue you referenced, however.

JSX would be picked up by the HtmlBock renderer, but you'd have to parse the JSX into a Javascript AST or do it ghetto-style with regular expressions (which would be super shaky). Even with an AST, you'd have to then reference the component names to local component names etc. It all seems like a lot of work, and isn't really what react-markdown was built for.

Having said that, I think the easiest way of going about it is to think of this as two separate parts:

  1. Parse a string containing JSX to an AST, then try to match components, variables, props and whatnot, in a way that you're able to call ReactDOM.render(rootJsxThing) on it.
  2. Hook that machine up to the HtmlBlock renderer. This is the easy part :)

I'm trying to keep open issues down, and I feel like this issue isn't necessarily tied to react-markdown, so I'll close it for now. I'd love to hear back from you if you have any progress in this, however. It's a pretty interesting problem you're trying to solve!

@rexxars rexxars closed this as completed Mar 28, 2017
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

2 participants