Block Directives

TL;DR: Perhaps block directives shall just support fenced characters that are frequency used in commonmark. (e.g. backticks in code blocks)

Hmmmm… well I like the format. Would perhaps restricting to 3 types of fencing be okay, based on how we want it to behave when in an implementation that doesn’t recognize generic directives at all?

###Three types of fencing to support to ensure acceptable fallback:
(note: Please suggest other characters, if you like the concept, but not the fencing characters)

(1) Display as code block ( e.g. codes or ASCII art )

!python:
````````````````````` {.python}
print("Hello World")
`````````````````````

(2) Display as normal content ( e.g. spoilers ):

!spoiler:
!!!
harrys kills voltmort
But spares hermimi
!!!

(3) Hide block content from display ( e.g. settings or page declarations )

e.g.

!pandocStyleYAML:
---------------------
layout: resume
.....................


!jekellStyleYAML:
---------------------
layout: resume
---------------------

###Seems bit hard to do (2) … well what if…

(1) Display as code block ( e.g. codes or ASCII art )

`````````````````````!python {.python}
print("Hello World")
`````````````````````

(2) Display as normal content ( e.g. spoilers ):

!!!spoiler
harrys kills voltmort
But spares hermimi
!!!

(3) Hide block content from display ( e.g. settings or page declarations )

e.g.

---------------------!pandocStyleYAML
layout: resume
.....................

---------------------!jekellStyleYAML
layout: resume
---------------------

What’s your opinion? Can you provide a visual example of what you want? I can show how I see, but kind of hard to see your perspective. Perhaps show a few examples yourself as well.

!:cut
!:spoiler

content

```

Or

!!:spoiler
content
!!

Admittedly your second example looks better (Since the : in first example make it look rather ugly). Though do we really need : ?
Shouldn’t this work just as well, and is more visually simple.

!!!spoiler
content
!!!

The concern about this approach however, is the fallback.

This is how your two examples will break here. Is any fine with you? :

(1) (added a !!! block example of similar style)

!:cut

!:spoiler

content

!:spoiler
!!!
content
!!!

(2) (added a code block example of similar style)

content

!!!:spoiler
content
!!!


Anyhow I hope somebody else add their opinion. I think I made my own preference pretty clear. Which is directive before fenced block without !:). But I would like to know if there is any other opinions besides mine and vitaly.

Kramdown has a neat syntax to add attributes to blocks

> A blockquote with a title
{:title="The blockquote title"}
{: #myid}

Or in general

this is a paragraph
with some lines
{: .spoiler}

Or

{: .spoiler}
this is a paragraph
with some lines

Yes, I still like this syntax for block directives as well:

!!!name
content
!!!

or for that matter:

@@@name
content
@@@

with optional [label](arg){#myId .myClass key=val key2="val 2"} like:

@@@asciiDiagram[_lovely_ cat]{ width=100 }
  |\_/|
 / @ @ \
( > º < )
 `>>x<<´
 /  O  \
@@@

Maybe separating spaces should be allowed for block directives: [] () {}

The body/content for block directives could be optional as well, so this:

@@@youtube[Funny video](dQw4w9WgXcQ)

renders as:

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

while this:

see @wikipedia[Foobar]

renders as:

<p>
  see <a href="https://en.wikipedia.org/wiki/Foobar">Foobar</a>
</p>

And as @lu_zero mentioned, for simple cases attributes added to existing elements already suffice (see the proposed attribute syntax).

1 Like

Btw shouldn’t we keep to consistent attributes like this? I remember that for blocks in general, the {} goes at the last line. Thus for your ascii cat example:

!!!asciiDiagram: _lovely_ cat
  |\_/|
 / @ @ \
( > º < )
 `>>x<<´
 /  O  \
!!!
{ width=100 }

Also about your choice of @. Isn’t it already used by most commenter as a signifier for usernames? e.g. twitter uses it as username, discourse uses it for username as well.

Fenced code blocks in Pandoc, MarkdownExtra and Kramdown (and therefore the consistent attributes proposal) have the attributes on the first line. It’s kind of nice to see all the arguments/attributes before you start to read the code/directive content…

``` {.language-ruby}
x = 1
```

True, but shouldn’t be a problem with @@@name or when the [] in @name[] is mandatory.

It’s kind of nice to see all the arguments/attributes before you start to read the code/directive content…

Alright


@@@name is ugly, and people would hate to have to type that for usernames.

@name[] is ugly. What if people want to call directive without arguments. E.g. @TableOfContents or !cut etc…

Using ! is much safer, and is internally consistent, since is already used to embed images. So naturally !name[]() would imply special embedded content/declaration.

yeah, on the other hand @name kind of looks more special, extension-like than !name… I would like to hear how other people feel about this…

1 Like

Btw I’ve been thinking about the issue of the !cut example. As in how do you distingush between a single line inline directive vs block directive. Here is an example of the issue.

!cut "this is settings for a block directive, but how do you know that `!cut` is not inline?"

!cut this is a normal paragraph with `!cut` as an inline directive in the first line.

I think the solution is to use : as the block directive switch. This is since anything after : in a block directive is purely arguments for the directive only. Thus

!cut: "much clearer that this is for the `!cut` directive"

!cut this is a normal paragraph with `!cut` as an inline directive in the first line.

Unfortunately, this does mean that the block directive for !cut without argument is

!cut:

But I think that is a suitable compromise.

The following doesn’t work for you?

Inline:

!name

Leaf Block see leaf vs. container blocks:

!!!name

Container Block:

!!!name
content
!!!

each with optional [](){} behind the name.

The issue with your leaf block proposal is if people for some reason type !!!!!! for some reason e.g.

!!!LeafBlock settings=value

some paragraph words etc....

!!!!!!!!!!!! WARNING !!!!!!!!!!!!!
   Well.. its a warning message.
      What did you expect?
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

now compare to this parser safer method:

!LeafBlock: settings=value

some paragraph words etc....

!!!!!!!!!!!! WARNING !!!!!!!!!!!!!
   Well.. its a warning message.
      What did you expect?
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Now it will leave the bit inbetween !LeafBlock and the last !!!! alone, and thus wont get confused.


No particular preference about the optional [](){}. As usual, if it’s optional then that’s good. I’m just covering @vitaly 's preference to keep the block param flexible.

Spaces between the @/! and the name should not be allowed: !!! warning is not valid while !!!warning is. Or should it be @@@warning to decrease the probability of clashes even further? :wink:

That warning block in example is not a directive btw. It’s just a style I see people randomly type in instruction manual, on things that people shouldn’t do if they want to not die. Basically its used in the wild as an enclosed box that is empathised for visibility.
(Wonder if we should make an ‘emphasis’ block where !!! <Important Block> !!! as the start header, and !!! for the end header. Edit: Content Block/Inline Syntax )

Of course. And if we disallow a space between the !!! and the name-part it stays that way, even in my proposal. (that was my point)

I see. What about people doing the insane thing and using !!!!!! as a divider:

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 Can you handle this now? Hahaha
    What did you expect? :D
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

or even:

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

          ! WARNING !
 Can you handle this now? Hahaha
    What did you expect? :D

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

I don’t like idea to add [](){} into spec for blocks. Looks like attempt to invent something universal with inlines without real needs. If you go this way, you can get html-like result in the end - working, but overcomplicated and not relevant to initial goal.

May be, {} only, but also under question.

That can work, but require parser to know exactly if named block is leaf or container. Because blocks can be nested. If you change parser to another one, that don’t know some named block directives, nesting sequence will become broken.

1 Like

I’m not sure I understand. The point of my proposal is exactly to avoid this. Therefore a leaf block is !!!name on one line, while a container block has an opening !!!name and a closing !!!. You agree that there should be a different syntax for leaf and container block directives, right?

The [inline content] (argument) {key-value pairs} serves simply as a common way to supply the directive with these three things, which I think is equally useful for inline and block directives. I’m thinking of what kind of AST a custom filter or module would like to receive after a markdown parser has parsed the document. An AST that contains something like:

LeafBlockDirective:
  - name: String
  - parsedInlineContent: InlineBlocks
  - unparsedInlineContent: String
  - arg: String
  - attributes: Map(String, String)

Examples use cases for [](){} in Leaf Block Directives:

  • @@@youtube[title of *funny* video](09jf3ow9jfw)

  • @@@video[title](filename.mp4){width=400}

  • @@@snip[label](path/to/code.scala)

  • @@@include(other-file.md)

  • @@@toc[*My* Contents]


It’s crossed my mind that :: might also be a suitable replacement for the @ or !.

Inline:

::name[optional inline content](optional arg){optional key-value pairs}

Leaf Block:

:::name [optional inline content] (optional arg) {optional key-value pairs}

Container Block:

:::name [optional inline content] (optional arg) {optional key-value pairs}
further block content
:::
1 Like

Sorry, i’ve mistyped. I wished to say that, that there should be way to differ one line and multilline block directives.

1 Like