micromark / micromark-extension-directive

micromark extension to support generic directives (`:cite[smith04]`)
https://unifiedjs.com
MIT License
31 stars 16 forks source link

Default name for container directives #12

Closed stormwarning closed 2 years ago

stormwarning commented 3 years ago

Initial checklist

Problem

The generic directives proposal indicates that container block directives with no name should fallback to a div, as in:

:::
Hello world
:::

Currently it seems that "nameless" blocks don't get picked up as directives at all when I do something like:

if (node.type === 'containerDirective') {
    console.log(node) // This code is not reached.
}

Solution

It would be great if "nameless" blocks were still picked up as such, as it would — at least for my use case — keep the markdown cleaner.

Alternatives

Just writing :::div and living with the pain, I suppose.

wooorm commented 3 years ago

The generic directives proposal indicates that container block directives with no name should fallback to a div, as in:

Where does it do that?

As I understand it, generic directives are required to have a name, and map to unknown content by default rather than HTML directly. That way, assuming GitHub would support directives, it could still parse users directives, even if it doesn’t understand what a ::youtube directive means.

stormwarning commented 3 years ago

Where does it do that?

First post, third section (Container Block Directives), sixth code example.

Even if it doesn't map to HTML directly, just being marked as a containerDirective would be helpful (at least for my own case).

wooorm commented 3 years ago

Weird... It does only mention it with triple-colon syntax, not with single or double colon. I’d find it quit weird if : and :: would also become a div/nameless directive. There might be something to say for :{#id}, ::{color="blue"}, or ::[whatever], as in that it more clearly looks like a directive, but it’s still a complex rule to learn that : and :: directives can be nameless if they do include labels/attributes.

But it’s also a bit of a weird rule to only allow ::: directives to be nameless?

wooorm commented 3 years ago

Note that this extension doesn’t 100% follow that post, as it’s a vague proposal from years ago. Most important to me is matching with how CommonMark works (e.g., ``` for code, or ```js, but not allowing ```js```, so we don’t allow stray colons at the end).

stormwarning commented 3 years ago

I first became aware of the ::: style of block syntax when using VuePress although now that I look at the updated docs, it seems like it might not work without some kind of attribute following the :::...

I agree that for the the Inline and Leaf directives being nameless seems a bit wrong — for most cases I would imagine one would intend to use it with a specific HTML element in mind — but a generic Container directive to me relates to a "callout" or "well" section in a page layout — a way to call attention to an entire bit of content, without really saying anything specific about the content (as opposed to ``` which indicates the content within to be code, for example).

stormwarning commented 3 years ago

Anyway, I appreciate the consideration (and all the effort behind micromark, unified, et al) — if you're not convinced it's worthwhile, feel free to close this issue, otherwise I'll see if I can continue my case in the morning 😉

wooorm commented 3 years ago

I’m leaning towards keeping name required. I see them more as a semantic annotation, a component, that might map to simple (or very complex) HTML. And the semantics as tied to the name. It depends on a bit on more information about what you want to do, but perhaps using :::callout or :::well could solve it?

And that VuePress also requires it, doesn’t help the case.

Note also that there is a somewhat similar but different idea, fenced divs: https://pandoc.org/MANUAL.html#divs-and-spans

wooorm commented 3 years ago

Maybe @ChristianMurphy has thoughts on this?

stormwarning commented 3 years ago

Maybe it's worth raising as a separate issue, but allowing a space between ::: and the name as in the VuePress/markdown-it implementation would, IMO, help keep the markdown more plaintext-friendly. (Would only make sense for the container directives, maybe for the leaf, as the inline format would get less readable with a space after the colon, and likely be a headache to implement)

For my own case, I'm trying to implement something similar to the VuePress container, but since I don't need to have different options for styling, I thought a bare ::: block would keep the raw markdown clean. So

:::
**Remember:** these utilities rely on the `.font-features` class to activate 
blah blah blah...
:::

vs

:::reminder
**Remember:** these utilities rely on the `.font-features` class to activate 
blah blah blah...
:::

Now that I look through my content, having the Inline directives have a default name would help keep the inline content clean as well...

in :[3]{.sups}He we want the :kbd[3] superscripted

vs

in :span[3]{.sups}He we want the :kbd[3] superscripted

(The className attribute on there as well might throw a wrench in my whole argument as that isn't helping readability either, but I think it's still a bit of an improvement)

ChristianMurphy commented 3 years ago

Maybe @ChristianMurphy has thoughts on this?

:thinking: I could see ::: acting similar to JSX, specifically like a fragment. JSX supports <></> for wrapping blocks but there is no inline equivalent shorthand. That said it's also a bit trickier, since fragments have distinct open and close tags, while ::: is ambiguous. :thinking:

wooorm commented 3 years ago

I think I really prefer :::reminder, :span, and :kbd in these examples. Even for just a div or a span with some attributes.

And nameless containers would indeed make parsing complex. Pandoc fenced_divs therefore requires one or more attributes (it includes the name in that term) on the opening. But I think that’s also a complex rule. And would make the nameless container as discussed here impossible

wooorm commented 3 years ago

JSX supports <></> for wrapping blocks but there is no inline equivalent shorthand. — @ChristianMurphy

How do you mean for blocks only? <p>Text <>and</> more</p> is valid JSX and an “inline” fragment?

ChristianMurphy commented 3 years ago

How do you mean for blocks only?

I mean, fragments shorthand has no self closing tag.

github-actions[bot] commented 3 years ago

Hi! Thanks for taking the time to contribute! This has been marked by a maintainer as needing more info. It’s not clear yet whether this is an issue. Here are a couple tips:

Thanks, — bb

wooorm commented 2 years ago

Going to close it. Seems we can’t find consensus on a good solution for this at the moment. Perhaps directives should fundamentally be named? And another extension like this should/could add a separate attribute syntax to add classes to things?