mdx-js / mdx

Markdown for the component era
https://mdxjs.com
MIT License
17.71k stars 1.14k forks source link

Global <MDX> or md`` function support #736

Closed wangyi7099 closed 4 years ago

wangyi7099 commented 5 years ago

Subject of the feature

I have known mdx has supported global component , like so:

<MDXProvider components={/* global components*/}></MDXProvider>

Is there a way to support global function ?

Problem

I want to create a markdown parse function so that I can parse markdown anywhere in mdx. Likes so:

// global markdown parse function
function mdParse() {
// .......
}

And in a markdown

<AlertComponent title={mdParse`# hellow world!`}/>

But now, I can only use the tag format, like so:

<AlertComponent title={<MD># hellow world!</MD>}/>
function MD({children}) {
 return mdParse(children)
}

It is not convenient!

Is there a change? Thanks!

Expected behavior

<MDXProvider functions={{mdParse}}></MDXProvider>

In markdown:

<AlertComponent title={mdParse`# hellow world!`}/>
johno commented 5 years ago

Right now you can achieve this with blank lines after the opening and closing tags (as specified by CommonMark):

<AlertComponent>

# Hello, world!

</AlertComponent>

The blank lines "reopen" markdown parsing. Does this fit into what you're wanting to achieve?

wangyi7099 commented 5 years ago

@johno Thanks for the reply! I'm afraid not. What I mean is that I can pase the markdown anywhere. Like so :

<Button/> md`#hello` 

Using a function seems to be more flexible, and also what if I want to do some other things or pass more markdown as props to more complex component ? Like so:

<Model head={md`#head`} body={md`#body`}>
</Model>
johno commented 5 years ago

Hmm, yeah I see. 👍

We've discussed this before (though mainly as a <MDX> component). This won't be something we'll look at implementing until after #628. But, I can see how providing more granular usage for MDX strings could be more flexible.

Also, if anyone has thoughts on how this could best be achieved/implemented please chime in!

wooorm commented 4 years ago

I think <Button/> md`#hello` is a bit weird: After a button, I would expect more Markdown, not JavaScript?! In an expression, sure: <Button/> {md`#hello`}. But <Button/> *hello* should be a button followed by emphasized text, not something magic?

If we’re going with that, then md can be implemented in userland: it could be a library that users import at the top, and which transforms the given markdown to <h1>hello</h1>.

johno commented 4 years ago

Really appreciate the suggestion but with v2 we’re going to support much more powerful interleaving but no inline MDX support for expressions. Though this should be achievable with a Babel macro.

felipecrs commented 7 months ago

I'm REALLY struggling to make something like the below work:

import data from "./changelog.json";

From: {data.from}  
To: {data.to}  
Updated: {data.updated}  

## Releases

{data.releases.map((release) => (

<div>

## ${release.tag}

Date: ${release.date}  

</div>

))}

But I just can't make the contents generated by the map be parsed as markdown.

I would super appreciate any ideas.

wangyi7099 commented 7 months ago

已收到

remcohaszing commented 7 months ago

You can create 2 MDX files.

{/* release.mdx */}
<div>

  ## ${props.release.tag}

  Date: ${props.release.date}  

</div>
import data from "./changelog.json";
import Release from './release.mdx';

From: {data.from}  
To: {data.to}  
Updated: {data.updated}  

## Releases

{data.releases.map((release) => <Release release={release} />)}
felipecrs commented 7 months ago

Oh I didn't need the <div> btw, it was just so accorn wouldn't freak out.

And it worked. SUPER thank you @remcohaszing!