Generic directives/plugins syntax

FWIW, I also like this syntax more than the current proposal. Not because of the JSON similarity, or any really objective reasons - it just seems easier on the eyes and more natural (to me it seems to reduce the readability burden that an attribute has on the reset of the text).

1 Like

I think that just stating either the syntax for extension (so it fits in the AST and could be provided to additional parsers easily) would be nice to have, but I’d stop there.

I’d rather have support for attaching generic attributes to block and inline elements as kramdown does.

Nearly agree (As long as we use !), but I want to add that the specification should encourage users/developers to check and maintain a list of commonly used extension names and input format conventions (Just like how there is a convention for port numbers). The actual extension output won’t be defined explicitly, just the input (Think prototypes in C Function prototype - Wikipedia )

Ergo: Just maintain this list Generic Directive Extension List ¡ commonmark/commonmark-spec Wiki ¡ GitHub , and keep to this psudo standard if possible.


Furthermore, if we use !, how does an indirect image like ![alttext][ref] get interpreted? This can’t be parsed as a directive, so that still remains as a special case?

  • ![]() --(means)–> !default[]()

Yes, but I asked about ![][], not ![]().

oh, good point. Hmmmm… Well maybe we can treat [] internally as an array of [] if that makes sense.

![alttext][ref] —> !default[alttext][ref] —> !image[alttext][ref]

where the image directive is smart enough to detect that the second [] is not empty.


This mean the general directive format is more accurately seen as

!name[][]etc... ()()etc... {}
  • array of [] called contentArray
  • array of () called argumentArray

{} is singular since it’s key value based.

Thought most of the time, we would typically just use one or two []

That actually sounds reasonable to me - there might even be directives that need multiple content values and no argument or the inverse, or more than two values total, etc.

One problem I can imagine is when a directive is followed by a link:

!foo[bar] [baz][bla]

Is this the foo directive followed by a link (text baz, reference bla) or is this a single directive with three content values? Not sure if this can really be prevented - escaping won’t help here since nothing should be displayed verbatim…

Well we stick to the same rule as usual. All bracket needs to touch to be considered part of the same directive

Oh right. I was under the impression that whitespace was allowed between the two parts of a link, but that’s no true. Makes sense to keep the same policy for directives, so my problem is resolved :slight_smile:

I don’t actually see the advantage of multiple explicit arguments. If you go back to the first posts, it says:

@name[content](arg){key=val key2="val 2"}

arg is a string to be interpreted by the custom directive that generally is not going to be directly visible (usually it is a URL or other identifier), and the {...} contain generic attributes (i.e. key-value pairs).

So if you want multiple URLs, write @slideshow[*My* pictures](img1.png img2.png) and the slideshow directive is free to split the string by spaces and interpret it as a list. I’ve always found it confusing to figure out when you could use multiple {}{} and [][] in LaTeX and ConTeXt and when not, so I’d prefer to avoid that in Markdown.

However, I agree with @Matthijs_Kooijman that we’ll have to think more about inline vs. block directives as it is rather vague in the above first post, i.e. to what AST should the following be parsed:

hello

@name[*my* text](some arg){key=val}

world

I can imagine two possibilities, either:

- Para: "hello"
- BlockDirective:
    content:
        - Em: "my"
        - "text"
    arg: 'some arg'
    attrs: {key: val}
- Para: "world"

Or:

- Para: "hello"
- Para:
    InlineDirective:
      content:
          - Em: "my"
          - "text"
      arg: 'some arg'
      attrs: {key: val}
- Para: "world"

The second would be more consistent, but it sometimes would require the module or filter expanding the directive to also replace the parent Paragraph which is nasty.

The mutiple [][] was to address the remote reference often used in markdown like so:

Reference-style image syntax looks like this:
![Alt text][id]

[id]: url/to/image  "Optional title attribute"

So was trying to think of a consistent way to deal with this.


If we do decided to break away from the old style of [][] reference, then maybe we could add a behaviour for the !default directive to keep to . Such that, if it detects a #id, then it knows to copy and paste from a different location.

Active Reference (Eqv to ![][] in markdown):

![Alt Text](#id) 

Passive Reference (E.g. citations) (Eqv to [][] in markdown):

[Alt Text](#id) 

linking to

[id]: ![Optional title attribute](url/to/image)

[id]:
[[[
    Block reference.
]]]

Ah, I see. You’re talking about reference links (and reference images). Well, I personally never use those so I never thought of having this for directives as well… but yes, if people really want that, it should be possible to come up with a workable solution.

Well it is part of original markdown standard

Why do we need any new syntax for block-level plugins?

Just use the standard ``` block syntax and hand off the opening line to the plugin parser.

```latex
[some latex stuffs]
```

```my-plugin foo, bar, {whatever:here} format=“doesn’t matter, markdown ignores this line”
[custom plugin syntax]
```

Just to prove the point, this block is the un-escaped version of the above.

Then the syntax (and the complexity thereof) is left up to the plugin and falls back to a mono-spaced block when the plugin isn’t available. IMO it’s very clean, very kind to users/writers of CommonMark, and has a very nice fallback.

1 Like

As far as a syntax for inline extensions. I think it would be useful to enumerate some concrete use-cases for such things so we have a better sense of how/why/for-what-purpose people are extending (or want to extend) Markdown.

Without having that data point you have nothing to ground your design decisions.

I read several things in this thread and others:

  1. Spoiler tags
  2. Embedding video and audio
  3. Embedding other files
  4. Latex/MathJax

IMO #3 is out of scope for CommonMark and is the job of a templating tool like Mustache, Handlebars, Razor, ERB, Dust.js, etc, etc.

Are there other use cases?

1 Like

The main idea is to make easy to extend CommonMark.

And include directive is more than welcome and part of the core CommonMark.

agreed.

A directive only specifies intent, not implementation. So it’s fine to use it for !include . Plus if it’s specific to a site, we want them to keep away from core syntax modification and just use directives if possible. This is so that it is easier to ignore and gracefully fail non-standard directives.

```latex
[some latex stuffs]
```

Should be restricted to highlighting code only. A directive may not necessarily display it’s content visually on unsupported implementations. Plus the ! in front of !name indicate it’s special status as a directive. Hence

!!!name
... content ...
!!!

Still wondering if this is not too bad of an alternative approach to block representation. What I think this can allow for, is selecting how it can fail. E.g. let [] be displayed visually if extension not found. While () is hidden from user view.

!name
[[[
    ... content ...
]]]

RE the block syntax:

I disagree on this point. Several concerns:

  1. I don’t think there should be any element that, by default, acts as a comment and yet isn’t an explicit comment syntax.
  2. I view ```thing as saying “hand this block off to a parser for ‘thing’”. Extensions would operate no differently than code coloring and the only change that would need to be made is to provide the initiating line to the extension so it can parse it if it desires to.
  3. Any syntax needs to be human-readable and easy for writers/authors/creators. Once the syntax starts including all manner of special control characters, it is more complex than just using HTML. Even the standard image and link syntax are very hard to remember, IMO the image syntax should be the upper bar of complexity of syntax in CommonMark.
  4. I’m concerned that in some cases this is outside the scope of what Markdown/CommonMark should be.

RE the inline syntax:

The various use cases you provided in Generic Directive Extension List ¡ commonmark/commonmark-spec Wiki ¡ GitHub are all very different. IMO that means there should be different discussions around such use cases and if it makes sense to provide a syntax for them.

For example, I like extending ![]() to mean “embed this resource” not “create an image tag”. It is keeping with its semantic use and the spirit of MD. But that use-case is completely different (both semantically and to a user) than providing behavioral interaction ala a spoiler tag or generating content ala a table of contents and as such, it shouldn’t have the same syntax. So, at a minimum, that should rule out ![]() as a generic extension syntax.

Further, I don’t see the point or purpose of defining additional fields like {}. All that needs to be defined are delimeters, and the rest left up to any plugins/extensions.

I’ll say again, there are massive assumptions being made when designing things in this manner and I don’t think it’s wise.

What is the “more complex” syntax? This:

<figure>
    <iframe width="420" height="315" src="//www.youtube.com/embed/dQw4w9WgXcQ" frameborder="0" allowfullscreen></iframe>
    <figcaption>Funny video</figcaption>
</figure>

or:

@youtube[Funny video](dQw4w9WgXcQ)

You said you would use code blocks for that. So you’d want the following?

```youtube
Funny video
dQw4w9WgXcQ
```

which CommonMark parsers should translate to:

<pre><code class="language-youtube">
Funny video
dQw4w9WgXcQ
</code></pre>

I appreciate that not everybody has use for custom directives, but many people do. And for those it should be a great win if there is a standardized generic way to use and implement them. Keep in mind that I’m not advocating this to be part of “Core CommonMark”: it is a recommendation by the spec, not a requirement.

3 Likes

The use-case you used is the one I explicitly said is in-keeping with the spirit of Markdown.

For example, I like extending ![]() to mean “embed this resource” not “create an image tag”. It is keeping with its semantic use and the spirit of MD.

A theoretical !youtube[Funny video](http://youtu.be/dQw4w9WgXcQ) would render as “!youtubeFunny video” which, IMO, is a perfectly acceptable fallback since it still provides a link to the content and the exposed exclamatory declaration isn’t so jarring as to render the output confusing or meaningless.

But to specifically answer your straw man, no, I do not see any problem with this either:

```youtube
http://youtu.be/dQw4w9WgXcQ
```

It would render as an embed where a “youtube” plugin is available and as

http://youtu.be/dQw4w9WgXcQ

where no such plugin is available, it’s a reasonable fallback and non-breaking to existing implementations.


But even that doesn’t answer a multitude of other questions:

  • Why would you resolve this to a <figure> element?
  • Why an iframe instead of an object or video embed?
  • What if someone else wanted a different output format? Are there now multiple different potential outputs for “!youtube” depending on what site you’re posting on or what parser you’re using?