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

Transclusion of _inline_ markdown? #241

Closed
kylegach opened this issue Aug 28, 2018 · 22 comments
Closed

Transclusion of _inline_ markdown? #241

kylegach opened this issue Aug 28, 2018 · 22 comments
Labels
💬 type/discussion This is a request for comments

Comments

@kylegach
Copy link

Hi. Markdown file transclusion (MFT) is super cool, but I cannot find a way to do the equivalent when all of the markdown is defined in the same file. Something like:

// page.mdx
import FancyLayout from '../components/FancyLayout

# Title

[1] Parsed _markdown_ content

<FancyLayout>
  [2] More parsed _markdown_ content, in a fancy layout
</FancyLayout>

I would like [2] to be parsed as markdown, but not sure how, beyond defining it in a separate file and using MFT. I'd like to keep it all in one file, though, for the sake of non-technical authors. Do I need to somehow make FancyLayout an MDX-savvy component?

If it's relevant, I'm using gatsby-mdx on a brand-new gatsby-starter-default.

Thanks!

@silvenon
Copy link
Contributor

I’d also really love if this worked. However, sometimes you might not want that, so we need a way to opt in or out of that behavior.

If you have ideas for an API, shoot. :)

@kylegach
Copy link
Author

What if mdx exported a function that took in mdx-friendly syntax (as a string, I assume) and output parsed content. Then a consumer could make a component using that function and include it:

// page.mdx
import FancyLayout from '../components/FancyLayout

# Title

[1] Parsed _markdown_ content

<FancyLayout>
  <MDXParser>
    [2] More parsed _markdown_ content, in a fancy layout
  </MDXParser>
</FancyLayout>

Of course, that MDXParser (name tbd) could then be integrated within FancyLayout, for a better authoring experience.

For simplicity, you could also restrict MDXParser from allowing imports/exports (at least for my use case).

@silvenon
Copy link
Contributor

Interesting idea! I'll give it some thought and see what's possible and what isn't.

@kylegach
Copy link
Author

kylegach commented Aug 29, 2018

Thanks for taking the time to give it some thought, Matija.

In the meantime, I've discovered that the runtime offers what I was asking for (with the perf/bundle size caveat):

// page.mdx
import MDX from '@mdx-js/runtime'
import FancyLayout from '../components/FancyLayout'

# Title

[1] Parsed _markdown_ content

<FancyLayout>
  <MDX>
    [2] More parsed _markdown_ content, in a fancy layout
  </MDX>
</FancyLayout>

That'll work for me for the time being. I'm not going to release this project until ~6 weeks from now anyway.

Edit: Custom components work for [1], but not [2]. I suspect I need something like withMDXComponents, but that's not public (probably for good reason).

@ChristopherBiscardi
Copy link
Member

@kylegach fwiw, we use withMDXComponent in gatsby-mdx because we need to pass the context through to the runtime scope already.

iirc the markdown inside of a JSX block is actually an html block when existing as mdast right now, so when we do #195 (which I need to file an issue or a PR to handle for a use-case in gatsby-mdx actually) we should be able to recurse down the tree and parse children of the jsx nodes as mdx? I haven't thought this through all the way, but could try to dive into it when working on the JSX block parsing.

Using the runtime again as a component is an interesting approach. In gatsby-mdx we do that processing on the graphql side of things and ship a much lighter runtime. Perhaps we could implement that logic downstream for you and then push it back upstream to mdx-js/mdx after we get it working.

@kylegach
Copy link
Author

@ChristopherBiscardi — Sounds great! It's a bit over my head to contribute code, but I'm happy to help test pre-releases, write docs, etc...

@craigmcginley
Copy link

@silvenon Just curious if this is planned for development or if there is any timeframe formulated for this feature.

@silvenon
Copy link
Contributor

At the moment there hasn't been any further progress beyond what we've written here. It's not a trivial feature and I'm not even sure whether we should have it at all.

But it will be useful if you shared your particular use cases if this feature existed.

@craigmcginley
Copy link

Absolutely. My use case for this is pretty simple. I'm already using MDX for components with no Markdown children. But I'd also like to use React components to substitute for some basic Markup to wrap Markdown. For instance, since you can't currently do this:

<div class="background-color">
<div class="max-width">

# Section with background color
...

</div>
</div>

Perhaps MDX could allow for something like this:

<BackgroundColor>
<MaxWidth>

## Section with background color
...

</MaxWidth>
</BackgroundColor>

<MaxWidth>

## New section with no background color
...

</MaxWIdth>

I know GitHub Flavored Markdown supports wrapping Markdown content with certain HTML tags. I'm basically hoping for something similar with MDX, but making simple React components that just render the HTML would work as well, even if a bit overkill..

@eckdanny-osi
Copy link

I am evaluating both @mdx-js and mdxc atm...

We're talking about child blocks (in mdxc) rt? May be worth a glance.

The most typical use case for me sounds similar to @craigmcginley's. Something like:

import React from 'react';
export default ({ children }) => <div className="card">{children}</div>;
import Card from './Card.js';

<Card>

### Famous Quotes

> Goodbye cruel world!

</Card>

to become

<div class="card>
   <h3>Famous Quotes</h3>
   <blockquote>Goodbye cruel world!</blockquote>
</div>

@silvenon
Copy link
Contributor

silvenon commented Oct 4, 2018

It appears that all of us forgot to check if that syntax actually works in MDX 🤣

Edit yj7y73qwpv

It appears that it does, please confirm if this is what you wanted.

@ChristopherBiscardi
Copy link
Member

@silvenon oh, I don't think it works without the line spaces though, like:

<div>
> Nested **MDX**!
</div>

@silvenon
Copy link
Contributor

silvenon commented Oct 4, 2018

Yeah, it doesn't, but the extra newline is a way to tell mdx to parse the children as well. You still want to be able to write plain text. The extra newline seems like a small compromise for a use case that is not very common.

@kylegach
Copy link
Author

kylegach commented Oct 4, 2018

The extra newline seems like a small compromise for a use case that is not very common.

Agreed. Thanks for stumbling across that, @eckdanny-osi!

Feel free to close this issue.

@silvenon
Copy link
Contributor

silvenon commented Oct 5, 2018

It's best not to rely on this behavior because it currently works accidentally, it's not part of the spec. I'll leave this open for further discussion.

@Undistraction
Copy link

Undistraction commented Apr 26, 2019

FWIW I have a similar use-case to those outlined above. I need a way to divide markdown content into sections:

<FullWidthSection>

# Example 

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque sodales ante in purus dignissim, in fringilla sem volutpat. Suspendisse ac nisl aliquet, ornare nisi eu, auctor magna. Aenean ex sapien, faucibus a finibus non, fringilla vitae quam. 

Aliquam eu massa quis odio tempor fermentum ac at lorem. Nullam augue mauris, mattis vel tellus ac, vestibulum interdum arcu. Cras rhoncus sapien at eros bibendum maximus. 

- alpha
- bravo

</FullWidthSection>

<DecoratedSection>

# Example

Nullam augue mauris, mattis vel tellus ac, vestibulum interdum arcu. Cras rhoncus sapien at eros bibendum maximus. 

</DecoratedSection>

@elis
Copy link

elis commented May 1, 2019

I've also stumbled upon this and would like to avoid including the runtime as recommended.

As for the API - how about the ability to provide local (and/or exported) variables that will contain the MDX we want to transcode and then simply use it normally inside our components? e.g.

# My MDX Doc

import SomeComp from './my-comp'

const myMdxedContent = <<<
Some **random** (mdx)[mdxjs.com] string
>>>

<SomeComp>{myMdxedContent}</SomeComp>

@polarathene
Copy link

polarathene commented May 22, 2019

I ran into this issue trying out MDX, I detail it in a related issue at gatsby-mdx: #556

My example differs in that I have a component declared within a markdown paragraph, the component is an import of another MDX doc which just has two conditional wrapper components around markdown(conditionally render markdown based on prop/JS logic):

import InstallPath from './embeds/install-path.mdx'

In the Rust development environment, all tools are installed to the <InstallPath/> directory,
import PlatformSpecific from '../../components/detect-platform'

<PlatformSpecific unix>`/.cargo/bin`</PlatformSpecific>
<PlatformSpecific win>`%USERPROFILE%\.cargo\bin`</PlatformSpecific>

I thought that this would behave similar to the Button example in the playground:

Renders a button with text in italic

Here is a <Button>*button*</Button>

But this approach ended up being more like the following, which the playground also shows to render unexpectedly:

Renders a button with plain text `*button*`

<Button>*button*</Button>

You can use a blank line to work around that:

Renders a button but includes newline..

<Button>

*button*
</Button>

However that renders incorrectly, and in the intended usage within a paragraph similar to InlineCode, (well, my actual usage/component tries to return exactly that via markdown) a new line is forced breaking the paragraph.

Note a blank line isn't required afaik if you start with heading content #

@polarathene
Copy link

My issues appear to be due to not expecting the nested/wrapped MDX content to be wrapped within a <p> tag. That does make sense why the problem was happening, but I'm not sure how I go about avoiding that? Is there a way to opt-out for my embedded content?

@namelos
Copy link

namelos commented Jul 6, 2019

I encountered a similar use case that the empty line workaround doesn't work. I'm trying to build something similar to this document tufte-css

There are several block behavior in this page could be solved by empty line workaround, though not absolutely ideal:

<section>

first paragraph

second paragraph
</section>

However, the use case which bugs me most is:

<blockquote cite="http://www.edwardtufte.com/bboard/q-and-a-fetch-msg?msg_id=0000hB">
  <p>a bunch of paragraphs</p>
  <footer>
    <a href="http://www.edwardtufte.com/bboard/q-and-a-fetch-msg?msg_id=0000hB">Edward Tufte, forum post, ‘Book design: advice and examples’ thread</a>
  </footer>
</blockquote>

If I translate the code above to:

> a bunch of paragraphs
> <footer> [Edward Tufte, forum post, ‘Book design: advice and examples’ thread]("http://www.edwardtufte.com/bboard/q-and-a-fetch-msg?msg_id=0000hB") <footer>

The link would be lost and translated as literal.

If I do this:

> a bunch of paragraphs
<footer>

> [Edward Tufte, forum post, ‘Book design: advice and examples’ thread]("http://www.edwardtufte.com/bboard/q-and-a-fetch-msg?msg_id=0000hB")
<footer>

Not only it seems crazy but also there would be an extra <p> tag.

All I can do is:

<blockquote>

a bunch of paragraphs
  <footer>
    <a href="http://www.edwardtufte.com/bboard/q-and-a-fetch-msg?msg_id=0000hB">Edward Tufte, forum post, ‘Book design: advice and examples’ thread</a>
  </footer>
</blockquote>

But it seems the only thing MDX provides is just adding the <p> tag for the paragraph. As a result, I'm using HTML most of the time.

I just started doing this today, I found there could be many cases like this, which will require the ability to go back to markdown again ad-hoc-ly.

@silvenon
Copy link
Contributor

silvenon commented Jul 8, 2019

I haven't been following this thread closely, but this is one of the limitations of Markdown, it's not related to MDX. Your use case is very specific, not only does the blockquote have a footer, but it also uses the cite attribute, none of which Markdown supports. What could MDX do here that would make sense syntax-wise?

@johno
Copy link
Member

johno commented Sep 3, 2019

Thanks for opening the issue! Closing this in favor of the interleaving RFC #628 (which is currently partially supported, albeit undocumented, in v1).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
💬 type/discussion This is a request for comments
Development

No branches or pull requests

10 participants