Generic directives/plugins syntax

To mb21

I had another though about if we really should use @ over ! for images. Well what if ![](){} is just shorthand for !image[](){} or more generally !default[](){} which would detect url type and redirect to approtate extention like !youtube[](){} . If that is the case, then we can just treat ! as just another generic directive that already includes some image embedding extensions by default.

 !image[ img descrip ]( image url ){ .style }

This then allows for a visually compact block directive

 !!!image [ Image description ] () { .blockStyle type=png encoding=base64 }
     ... Base 64 encoded png image Content ...

Or if we include vitaly’s recommendation for readability in block directives (via adding a : , and just passing the entire string after !!!:image) :

 !!!:image png base64
     ... Base 64 encoded png image Content ...
 { .blockStyle }

Extra thoughts: to avoid polluting the directive namespace, uncommon extensions are place under extention. e.g. !extention.regexReplace as opposed to '!regexReplace`

Yeah using !name[] instead of @name[] could work as well. On the other hand, people might confuse it with images and !!!name has kind of a less horizontal vibe to it than @@@name.

I don’t find that adding a : makes it more readable, quite the opposite in fact. It is inspired by reStructuredText’s syntax and many people favour Markdown over reStructuredText exactly because of things like that.

1 Like

It’s inspired by looking at the display :slight_smile: . I’m not familiar with reStructuredText’s syntax.

!!: has the same length as !!!, and don’t confuse with images. I did not suggested !!!: - that’s too long. Anyway, it’s a question of personal preferences. We could vote at the end.

1 Like

That’s fair enough vitaly. Though I suspect that laziness in typing !!!name will win out at the end lol.


I don’t think people is likely to confuse !name[](){} with ![](){} as the extension name quantifier will be pretty obvious enough.

On the vibe of !!! feeling less horizontal than @@@. This is only really an issue on non monospaced displays, and I don’t think it is worth the hassle of having a wider vibe at the cost of requiring the users to remember additional symbols (which was my issue with reStructuredText (I’m lazy, and so is the majority of markdown converts). I think it is more beneficial keeping the ‘core syntax language’ small by conceptual reuse of ! as an extention directive (and treating embedded videos, and images as extensions of it).

Perhaps the part after the ! could correspond to the HTML tag itself. Examples:

!img[This is some alt text](filename.jpg)

!video[Your browser does not support the video element.](filename.mp4)

!audio[Your browser does not support the audio element.](filename.mp3)


I need to look into Web Components more, but my understanding is that they can be used to create custom HTML elements. If this is the direction that the web is going, we could potentially create custom elements for spoilers, etc using the above format.

Good point, haven’t thought about that. Let me know what you get.

At the very least, it provides a very handy html fallback, if there is no handler for such extensions.

There’s a good article on CSS Tricks explaining Web Components. From the article:

Creating your own HTML element might sound intimidating but it’s actually quite easy. In Web Components speak, this new element is a Custom Element, and the only two requirements are that its name must contain a dash, and its prototype must extend HTMLElement.

So you could potentially have a Web Component called <has-spoilers> which would correspond to !has-spoilers[]() in CommonMark (if we used the pattern I suggested).

I like it very much. E.g. how the massive html

<div id="slider">
  <input checked="" type="radio" name="slider" id="slide1" selected="false">
  ... blablabbalbla ...
  <label for="slide4"></label>

shrinks to

  <img src="images/sunset.jpg" alt="a dramatic sunset">
  <img src="images/arch.jpg" alt="a rock arch">
  <img src="images/grooves.jpg" alt="some neat grooves">
  <img src="images/rock.jpg" alt="an interesting rock">

However, after further reading, and noting the requirement of Javascript to access the shadow DOM to load the components. I think that while it is a good fallback, it is not a total replacement all use cases of directives. E.g. rendering mathematical plots to a static image.

If we do use this method. Just note that we might need to also enable CommonMark parsing within the block itself.

!extentionName: This should be **bold** yea.

!extentionName[This should be **bold** yea.]( argument ){.style}

!!!extentionName: argument 
   #A header here, if we are using the directive format as webcomponents
   This should be **bold** yea. And maybe we can make this a slider gallery too.
   ![ a dramatic sunset ](images/sunset.jpg)
   ![ a rock arch ](images/arch.jpg)
!!! { .style }

Yeah, I can see why you might want a block syntax to describe more complex components.

Was the choice of three exclamation marks to keep the syntax consistent with code blocks?

What is the argument part for (after extensionName)? If it is for a URL/filename, could this be closer to the image/link syntax? E.g. !!!custom-component(something.extension)

Was the choice of three exclamation marks to keep the syntax consistent with code blocks?

Yes it was. Keeping things similar, makes it easier to remember.

What is the argument part for (after extensionName)? If it is for a URL/filename, could this be closer to the image/link syntax? E.g. !!!custom-component(something.extension)

I think it’s better if its more like namespace in java where


This is since the format is:

!extentionName[ content ]( arguments ){ #id .Class arg1="" arg2="" argEtc="" }

This is since in a url, [] is alt textual description. () is for the argument input, e.g. url. and {} is for extra html settings (e.g. webcomponent), or keyvalue pair if an extension is found.

If we go with the web components idea, perhaps the hyphen could double as a namespace separator? E.g. !extentionname-component[](){}

I think we should specify custom directives in terms of a Markdown AST, not the HTML output. As such, implementations should be free to generate Web Components/custom tags when exporting to HTML, but we should think of it more broadly. However, I kind of like the idea that implementations could fall back to using the name in !name as the HTML tag if they don’t know the specified directive. On the other hand, using custom tags requires that you register them: so embedding a HTML snipped (generated form Markdown) that contains custom tags might make a document invalid.

About the !name instead of @name, I’m still on the fence. I guess it comes all down to whether we want images to be a special kind of directive (and use !), or whether we want directives to be a special markdown extension that should be easily distinguishable from Core Markdown (and use @).

Thinking about how Markdown processor would implement generic directives, I guess Pandoc wouldn’t necessarily have to add a new abstract data type definition but instead parse @name[*my* content](arg){.myClass key=val} to <span class="myClass directive-name" key="val" arg="arg”><em>my</em> content</span>. This would be enough for scripts manipulating Pandoc’s AST to pick up easily.

Encouraging people, who use extensions that are very specific to their use case, to prefix them with some kind of a namespace (like @namespace-directivename[]) is certainly a good idea. However, directives like @video that might be of use to everyone shouldn’t require a namespace, but there should be a registry somewhere on the CommonMark Github repo that lists known extensions and how they behave.

Finally, I still don’t like the :-syntax. I find it harder to read (where does it end?), less markdown-like (i.e. less like links/images) and I like Python’s motto of “There should be one—and preferably only one—obvious way to do it”.

1 Like

Fair enough about how : in !tl;dr: Summary Here is harmful.
I guess encouraging !tl;dr[ Summary Here] is not much more work.

… CommonMark Github repo that lists known extensions …

In regard to a registry of known extensions. I would encourage a registry similar to ‘IP port number list’, that defines the name, purpose, and input format ( But does not specify specific extension implementation, but only possible ones to use). Kind of like a linux ‘man page’,

!video[ desc ]( url ){ #id .class width=<num1> height=<num2> }
   Description: blabalba
   desc: Describes balblabl
   url: Links to blababl

… About the !name instead of @name, I’m still on the fence. …

If you are going to use @video[]() you might as well use ! at least for media, since it’s already implies embeddable media like pictures. e.g. !video[]() !audio[](). I suggested using ! as a directive signifier, since syntactically it already implies a more complex mapping of content to html.

The biggest point however, is that making images to be a special kind of directive, would allow for keeping it modular. This means better sandboxing of errors. And easier parsing. Since any issue can just be via fixing the image module. (Thus keeping the core parser as small as possible. After all, the smaller anything is, the easier it is to review.)

Btw, chrisalley’s idea for directives used as webcomponent declaration would map

!directiveName[*my* content](arg){.myClass key=val}

to (For illustrative purpose only)

<directiveName class="myClass" key="val" arg="arg”>
   <em>my</em> content

and only if it cannot find any internal extensions for !directiveName.

A middle ground?

Perhaps if you want it to be a way to distinguish @ from core markdown !, then how about treating @ as an extention of ! namespace for less commonly used extension. Where ! starts at root. namespace, @ would start at root.extention. .


maps to


As for why? Well, you can imagine stuff like !video and !audio would be used nearly everywhere, while @sendPMto for a specific site is of limited usage.

So the root namespace of ! would be more strictly defined, and can be assumed to work for majority of websites (that implemented these extensions). While the @ is a bit more site specific and ad hoc. Again, kind of like the philosophy between CommonMark strong speccing, and markdown’s anarchist leanings.

Annnnd, you could just restrict webcomponent detection to @ only. Thus minimising collision to ! namespace even further. (Since I envision that the same web components won’t really be used everywhere)
@unknownExt --> <unknownExt></unknownExt>

summery: ! for core directives. @ for ad hoc site specific directives.

@ is often used to signify usernames (on these forums for example). Using @ in Markdown could conflict with systems that also implement this convention, even if they are not strictly part of Markdown. I think it’s fine to use ! for more than just images. Multiple uses of ! would seem consistent for the writer’s point of view.

I can understand the desire to make programming the parser easier. I think users should come first though, even if it makes life harder for the programmer (see my response to @mb21).

1 Like

For better or worse, Markdown’s philosophy appears to be closer to Perl’s There’s more than one way to do it. Coming from Ruby, I actually like this, as it allows to writer to be more expressive. For example you can write if !(x) or unless x. Either syntax might be more readable depending on the context, just like in English. Best not to create variations without good reason though.

1 Like

@mofosyne why not use ||| over !!! for container blocks? Maybe it looks better.

|||extentionName: argument 
   #A header here, if we are using the directive format as webcomponents
   This should be **bold** yea. And maybe we can make this a slider gallery too.
   ![ a dramatic sunset ](images/sunset.jpg)
   ![ a rock arch ](images/arch.jpg)
||| { .style }


!!!extentionName: argument 
   #A header here, if we are using the directive format as webcomponents
   This should be **bold** yea. And maybe we can make this a slider gallery too.
   ![ a dramatic sunset ](images/sunset.jpg)
   ![ a rock arch ](images/arch.jpg)
!!! { .style }

aaren. I pushed for ! over something like | for syntactical consistency with ![](){} which consider to be an inline directive. There is not much visual difference to consider switching to | for visual prettiness reason. I want to push for a very small ‘base syntax’ people would have to learn, and memorizing that ! could be used for both inline and block directives is handy.

P.s. Plus I’m pushing for | to be used as a metadata field character.

I’d rather keep ||| for tables.

All in all @@@name[](){} and @name[](){} seem a better fit.

agreed lu_zero. Btw, would this make sense to you? That !extentionName is in root level, and @extention.extentionName is the same as !extentionName?


  • !coreExtention would be for officially included extensions ( like the default ![](){} --> !default[](){} --> !image[](){} ). Which can be reasonably expected to work consistently.
  • Plus the input is defined for the name as well in a community page (e.g. just as how IP ports have a general standard)


  • @uncommonExtention would be for site specific extensions. Stuff that is not commonly used enough to be included in root namespace.

Would help keep namespaces bit cleaner.

I think this is a very good reason for going with !. The less syntax that the writer has to remember, the better.

Earlier I raised an issue with using @ within Markdown. @ is commonly used to represent usernames. I do not think it should be used in Markdown for this reason.

1 Like