Block Directives


#1

A block directive allows for embedding or calling certain operations that does not require extending the core syntax.
(Note: There is a debate between ! vs @ as generic directive indicator. I prefer ! as it indicates embedded content or intent.)

Block Syntax

Block syntax, using repeated sequence as delineators. !!! & the code fence syntax is used to indicate if content should be treated as normal text or code blocks if no extension found. (Could also indicate to extension on the type of fencing used, might be useful)

Single Line/Leaf Block Directive

!extensionName: param
{#id .Style key=value}

Multiline/Container Block Directive

Fenced

Standard

(single space between !extensionName: and param)

!extensionName: param
< commonmark fencing start>
... content to read into !extensionName ...
< commonmark fencing end>
{#id .Style key=value}

e.g.

!extensionName: param
::::::::::::::::::::::::::::::::::::::::::::
... content to read into !extensionName ...
::::::::::::::::::::::::::::::::::::::::::::

compact mode

(no space after !extensionName:)

!extensionName:< commonmark fencing start>
... content to read into !extensionName ...
< commonmark fencing end>
{#id .Style key=value}

e.g.

!extensionName::::::::::::::::::::::::::::::
... content to read into !extensionName ...
::::::::::::::::::::::::::::::::::::::::::::

!extensionName:`````````````````````````````
... content to read into !extensionName ...
````````````````````````````````````````````

No Fence (For single paragraph content)

!extensionName: param
... content to be...
... read into !extensionName ...
... falling back as normal content if failed...

Some other paragraph that is not read into !extentionName

This also allows for content that falls back as code block (Good for ASCII art)

!extensionName: param
    ... this is code and it's content to be...
    ... read into !extensionName ...
    ... falling back as code block if failed...

Some other paragraph that is not read into !extentionName

HTML examples

standard directive

!extensionName: param
::: {#id .Style key=value}
... content to read into !extensionName ...
:::

falls back on missing directive as

<extensionName id="id" class="class" key=value >
... content to read into !extensionName ...
</extensionName>

code fenced directive

!extensionName: param
``` {#id .Style key=value}
... content to read into !extensionName ...
```

falls back on missing directive as

< extensionName id="id" class="class" key=value >
<code> ... content to read into !extensionName ... </code>
</extensionName>

##Directive example:

... paragraph ...

!cut:

... paragraph ...

!youtube: _VHfymfJCXs

... paragraph ...

!css: show=hide
`````````````````````
// ... insert css layout code that can be applied to this document..
// ... only if the site or program actually is willing to use it...
`````````````````````

!eval: python package=mathPy
`````````````````````````````` {.python}
# the {.python} doesn't get counted into the pattern recognition
# of end of declaration block, because either parser is smart enough to ignore {}
# or it recognizes... well somehow. I'm sure there is a way to make it work
print("hello world")
``````````````````````````````

!metadata: display
---
CommonMark: 0.1.23-github.username.projectname
title: Title for the top bar of any browser
layout: report
***

##Presentation Examples:

!graph: type="pie chart" inputType=csv x=Year y=Price
`````````````````````
Year,Make,Model,Description,Price
1997,Ford,E350,"ac, abs, moon",3000.00
1999,Chevy,"Venture ""Extended Edition""","",4900.00
1999,Chevy,"Venture ""Extended Edition, Very Large""",,5000.00
`````````````````````

!asciiDiagram: width=100 height=100 
```````````````````````````````````````````````````````
  |\_/|        ****************************    (\_/)
 / @ @ \       *  "Purrrfectly pleasant"  *   (='.'=)
( > º < )      *       Poppy Prinz        *   (")_(")
 `>>x<<´       *   (pprinz@example.com)   *
 /  O  \       ****************************
```````````````````````````````````````````````````````

!asciiDiagram: width=100 height=100 
      |\_/|        ****************************    (\_/)
     / @ @ \       *  "Purrrfectly pleasant"  *   (='.'=)
    ( > º < )      *       Poppy Prinz        *   (")_(")
     `>>x<<´       *   (pprinz@example.com)   *
     /  O  \       ****************************


!spoilers:
Snaper kills Dumton 
In Harry's Plot
This is good for large block of spoilers

##Single Line:

Though, if it’s a single line, wouldn’t it be easier to just use inline directives?

!spoiler: harrys kills voltmort

##Multiline:

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

Implement some form of block directive in your implementation? Note it down here!

http://www.reddit.com/r/LightWeightMarkup/wiki/commonmark/unofficialextensions

Some ideas for generic directive extensions plugins:


Custom container for block and inline
Irony: This forum doesn't use standard markdown
How can we get more non-programmers involved?
Generic directives/plugins syntax
Generic directives/plugins syntax
Fenced block but not fenced code block
#2

Suggestion:

  • Remove reference to inline syntax, there are no relation. This fix mind on wrong assumptions.
  • Split blocks by use types and add examples:
    • directives (more programmish)
      • multiline
      • single line
    • presentation
      • multiline (spoiler - can be nested)
      • single line (cut)

It’s a bit not convenient to go for info by link. And that info is still mixed with inlines.

Main questions:

  • How to decide, if block is multiline or single line? Should it be done on markup level or parser level?
  • How to decide if block can be nested or not?
  • For nested blocks:
    • can we fix indent strictly to 0 (in parent container)?
    • what is rule to find end of block in list or blockquote?
  • What are reaseons to have this syntax instead of fenced block (at first glance - nesting without offset change and single-line markup/directives.

#3

The 4 examples are just variation brainstorming. Basically we could choose one of em, depending on how people here think (unless there is another better syntax).

Trying to answer your questions

  • How to decide, if block is multiline or single line? Should it be done on markup level or parser level?
  • Maybe via paragraphs or via [[[ and ]]]
  • How to decide if block can be nested or not?
  • Not too sure how to answer that. Maybe somebody else here can chip in.
  • For nested blocks: can we fix indent strictly to 0 (in parent container)? what is rule to find end of block in list or blockquote?
  • I’m experimenting with [[[ and ]]]
  • What are reasons to have this syntax instead of fenced block (at first glance - nesting without offset change and single-line markup/directives.
  • I would guess keeping numbers of lines to a minimum would be a reason for that.

As usual more brainstorming

Hmmm… maybe this could be an approach. What if : at the end of !name[](){}: means that the next paragraph/block/grouping is part of it. The benefit to this, is it allows for better fallback. The detection of block mode by :, might change the ![](){}: to act as a settings input perhaps (depending on extension). Perhaps, you can make it so, that :![](){} below a paragraph, indicates that the above paragraph/block is the input to the directive.

# paragraph fallbacks as a paragraph #

!extentionNames[ lineContent ]( argContent ){ #id .class key1=value key2=value }:
... Paragraph to be parsed by !extentionName ...

# Quotes #

!extentionNames[ lineContent ]( argContent ){ #id .class key1=value key2=value }:
>... Paragraph to be parsed by !extentionName ...
> 
>... while being able to fall back as if it was a block quote.

# Placing directive setting below block to be parsed by extention#

>... Paragraph to be parsed by !extentionName ...
> 
>... while being able to fall back as if it was a block quote.
:!extentionNames[ lineContent ]( argContent ){ #id .class key1=value key2=value }

# directive falling back as a code block #

!extentionNames[ lineContent ]( argContent ){ #id .class key1=value key2=value }:
``````````
... content that falls back as normal monospaced code ...
``````````

directive with multiple paragraphs and a nested directive

To try and keep to your desire to keep indent to 0 for nested directives I’m trying the ---[ method (any other better ideas for the nesting? )

!extentionNames[ lineContent ]( argContent ){ #id .class key1=value key2=value }:
[[[
... Paragraph1 to be parsed by !extentionName ...
... Paragraph2 to be parsed by !extentionName ...

!extentionNames[ lineContent ]( argContent ){ #id .class key1=value key2=value }:
----[[[
... Paragraph1 to be parsed by !extentionName ...
... Paragraph2 to be parsed by !extentionName ...    
----]]]

## Is the same as above nested extension ##

    !extentionNames[ lineContent ]( argContent ){ #id .class key1=value key2=value }:
----[[[
    ... Paragraph1 to be parsed by !extentionName ...
    ... Paragraph2 to be parsed by !extentionName ...    
----]]]

]]]

what’s with ----[[[?: I think this would essentially say that that “this group of paragraphs/block” is nested. Which means you can optionally indent it up the end of ---- without it turning into a code line until 4 spaces later. This allows you the flexibility of choosing to indent for visibility or not indent for flexibility.


The appeal of below form, compared to the above idea, is that the below form is much more different than the inline syntax, which would in theory make it easier to use by being less confusing…

!!!ExtentionNames: argument { #id .class key1=value key2=value }
...blockContent...
!!!

#4
  1. !{}, !!![[[ - i don’t like this. Looks as ascii art.
  2. Why not leave params interpretation to block author?
  3. Collect examples. Without use cases discussing syntax will be too abstract.

#5

… Moved to first post …


#7

I mean, collect examples in structured form (directive/presentation + single/multiline) in first post, as summary of current state. All need an easy way to understand, why we discuss block syntax, and which cases should be verified.

Yes. I don’t see reasons to force all those {} here. Using block means you already wish something very custom. Defining groups of params looks like overcomplication. At least, until we have proofs (lot of real examples), that it’s really needed.


#8

Okay, modified the first post to hopefully make it clearer and to the structure you preferred (and added a bit extra to it).

The examples added leaves param interpretation to block author.

I’m hoping others like @chrisalley might have some examples to spare. I’m a bit out of ideas personally. Well what applications do people need block directives besides letting the renderer know to render ASCII to svg or something like that.


#9

Awesome.

Note1: single line blocks without params will look a bit strange:

...

!cut:

...

Question. What reasons were to use ruler-style separators to mark start/end? Seems i missed this discussion.

Note2: In serarator it’s better to avoid chars, used to mark fenced blocks. That will greately simplify seeking block end.


#10

I was considering minimising lines by using !!! format, but you said it looks bit too much like ASCII. Also the reason for ruler-style seperators is to make it clear when the start and end is.

Also it makes for good fall back for code blocks directives e.g.

!asciiDiagram: width=100 height=100 
```````````````````````````````````````````````````````
  |\_/|        ****************************    (\_/)
 / @ @ \       *  "Purrrfectly pleasant"  *   (='.'=)
( > º < )      *       Poppy Prinz        *   (")_(")
 `>>x<<´       *   (pprinz@example.com)   *
 /  O  \       ****************************
```````````````````````````````````````````````````````

looks like this, in an unsupported system (where no fenced block is supported), and for pandoc with fenced code support, it can recognize the box as a fenced code still. :

!asciiDiagram: width=100 height=100

  |\_/|        ****************************    (\_/)
 / @ @ \       *  "Purrrfectly pleasant"  *   (='.'=)
( > º < )      *       Poppy Prinz        *   (")_(")
 `>>x<<´       *   (pprinz@example.com)   *
 /  O  \       ****************************

For your cut example, would this format work? Single line directives is:

...

!extentionName param

...

Thus:

...

!cut

...

So in this context : means this is a multiline block. So lack of this, indicates it is a single line block.

Alternatively, we could just keep the same logic as above, but just make : an optional extra, for visual stylistic purpose.


In separator it’s better to avoid chars, used to mark fenced blocks.

What do you suggest?


note: first post updated.


#11

For !cut it could be difficult to distinguish between inline and block. Right now no problem, but possible collisions in general case.


#12

A block must be placed on the start of a line, and have a blank line on top.

This means, collision is only possible at the very first line of a paragraph, solvable via a space if want inline. Thus:

Block:

!cut this para

Inline

 !cut this para

#13

A have no best suggestions now. Still consider this as alternative:

!!:name optional params
...
!!

#14

!css should be implemented using the {} attribute syntax. The rest looks nice.


Generic directives/plugins syntax
#15

I thinked a bit more. Visually, i like ```````````````````-style separators for multiline blocks. If we require, that end separator exactly match start, that should help to resolve possible conflicts with fences. Because blocks will require more backticks than fences.

But should we force user type such separators by spec? Can it become boring on practice?


#16

Well that’s the idea behind giving people the flexibility of choosing how their fenced block may look like.

I did try thinking of what a “fenceless” paragraph look like, and it’s not that good. Plus it makes it hard to deal with multiline blocks like so:

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 

!extensionName:
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 

Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. 

Thus by letting people define their own “fence character” for directives it would be more obvious, and would also drastically reduced chances of collision with other fenced syntaxes.

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 

!extensionName:
000000000000000000000000000000000000000000000000000000000000000000 {.style}
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 
000000000000000000000000000000000000000000000000000000000000000000

!extensionName:
`````````````````````````````````````````````````````````````````` {.python}
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 
``````````````````````````````````````````````````````````````````

Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. 

Specially detected block :

Perhaps we should amend the flexible fence concept, to allow for detection of “special blocks” (which I think lu_zero wanted in terms of the {} syntax) (And I think there is some others like pandoc YAML block --- , ...)

(Oh, and another thing added. The directive will ignore the ‘{}’ attribute in beginning of flexible syntax, for determine the flexible fence characters.)

!extensionName: param
< repeated sequence of character | or | Start block of a special markdown block > {#id .Style}
... content to read into !extensionName ...
< repeated sequence of character | or | End block of a special markdown block>

Allows for ::

|| Pandoc’s YAML --- , ... (Though I would say it’s better to just use --- ):

!YAML:
---
title:  'This is the title: it contains a colon'
name: Author One
affiliation: University of Somewhere
...

|| CSS/C/etc… {} style as proposed by lu_zero… doesn’t look good tho. And potentially dangerous) :

!css:
{
    body {
        overflow: hidden;
        background: #000000;
    }
}

Overall, the biggest pro for flexible fencing for directives is that leverage the commonmark fencing tradition of “repeated characters for start and end markers”, and has good collision resistance.


#17

I’d restricted fensing char types to limited number. No need to make flexibility in places, where it’s not required. We need to provide something visually attractive and easy to type, but not unlimited ascii art.


#18

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.


#19
!:cut
!:spoiler

content

```

#20

Or

!!:spoiler
content
!!

#21

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.