Div block syntax


#1

Wow! This topic has been discussed by many folks across numerous threads for a long time. I don’t believe it’s been resolved, but div syntax is certainly something that’s been wanted for quite some time. For your consideration, some givens, a few observations, then a possible solution.

Givens

:arrow_forward: Markdown already supports side-marking syntax for blockquotes (>). It works great.

:arrow_forward: Pandoc supports a delimited / fenced syntax for code blocks (using ~~~, and also backtick).

~~~
10 print "hi"
20 goto 10
~~~

That delimited syntax works really well.

Opening mark is the same as the closing one (unlike, say {{{ ... }}}).

:arrow_forward: Side-marking syntax is easier to read. Delimited syntax is more of a convenience for writers (doesn’t read as well, but makes it easy to cut/paste into delimited blocks).

:arrow_forward: Commonmark / Pandoc / Markdown needs a syntax for divs; both a side-marked and a delimited syntax.

:arrow_forward: Side-marking looks best when the character/glyph is at least sort of vertically-oriented. Delimited syntax looks best with a horizontally-oriented character.

:arrow_forward: You want to choose a syntax that is markdownish. To me this means:

  • It shouldn’t look too much like markup,
  • shouldn’t be hard to remember,
  • should be mostly obvious to the reader what it means,
  • tough one: should just look good, catch on easily, and be resistant to going out of style (tall order!)
  • no overly ornate syntax. Ideally, readers should almost not even notice the syntax.

:arrow_forward: You’d like the syntax characters to look like what they mean (like how > looks like "indent this to the right). But divs don’t have any palpable meaning…

Observations

:arrow_forward: People like the colons, but they don’t really look great repeated (":::"). They also conflict with definition lists (if your flavor of markdown supports those). Exclamation marks look like yelling. Not many characters left to choose from!

:arrow_forward: Some commonly used block-like “syntax” I’ve seen or used:

+++ John wrote:
> What time does
> your flight land?

,---[ cooking tip ]---
| If it's burnt, you
| cooked it too long.
`---

-------- Warning --------
Keep peanut bag closed
to avoid squirrel attack!
-------------------------

Conclusion: headers work. Everyone knows immediately on-sight what they’re supposed to mean. They’re great.

:arrow_forward: It’s becoming increasingly clear that the way to style things is to put that info in curlies: {.some-class #some-id foo="bar"}. Note, Pandoc has recently added support for styling spans: [foo]{.bar}.

Proposed Solution

Edited using improvements added below-thread.

; --- {.warning}
; Toast is very hot. Butter
; with care, and handle only
; with tongs.

That is, the div character (; or !) followed by three or more dashes, and optionally the metadata for the div in curlies. For simple ones like the above, curlies and dot are optional. Further, trailing dashes allowed.

; ---------- info -----------
; Tea is now available in
; the dining car. Please sip
; quietly.

Nested looks like you'd expect:

; --- {.outer}
; Please make sure your feet
; are clean before entering the
; pool.
;
; ! --- {.inner} ---
; ! Hey, this
; ! means you!
;
; Mats are located by
; the entrance.

Delimited syntax:

; --- {.info}
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore
magna aliqua. Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea.
; ---

Though, I think it looks better with more hyphens:

; --------------------------------------------- {.info}
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore
magna aliqua. Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea.
; ---------------------------------------------

Nested works as you'd expect:

; --- {.outer}
Outer block!

; --- {.inner}
Hi from the inner block!
; ---

Back to outer.
; ---

Some nice benefits of this solution:

  • side-marked and delimited syntaxes mesh nicely together
  • meshes well with current md syntax (fenced code blocks, side-marked blockquotes)
  • doesn’t look too much like markup (or less like markup than, say, something like {{ ... }})
  • div character “;” doesn’t have any strong connotations (like how > is “shift right”, or even how : could be associated with definitions). ! has connotations for warning/caution/attention, which is often wanted.
  • the div headings ("--- {.some-class}") actually add readability; without the “---” it might look like gibberish content on the first line
  • the delimited syntax only adds one leading character, and then lets you use dashes, which look great.

Seems to me like it may be the least controversial way forward. Thanks.


#2

See also: https://talk.commonmark.org/t/content-block-inline-syntax/815.

I note from that thread that there was some interest in using ::: to delimit blocks. I think that proposal loses traction because those colons don’t make a very attractive horizontal delimeter, but I think the general idea of using the top line as a header with “{.styling}” info is good.

Example from that thread, using above div syntax (both side-marked and delimited):

::::::::::::::::::::::: WARNING  ::::::::::::::::::::::::::::
            # rm -rf / – Deletes Everything! #

  The command rm -rf / deletes everything it possible can,
 including files on your hard drive and files on connected 
                 removable media devices. 
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

vs.

; ------------------------------------------------- {.warning}
            # rm -rf / – Deletes Everything! #

The command rm -rf / deletes everything it possible can,
including files on your hard drive and files on connected 
removable media devices. 
; -----------------------------------------------------------

and

; ------------------------------------------------- {.warning}
;           # rm -rf / – Deletes Everything! #
;
; The command rm -rf / deletes everything it possible can,
; including files on your hard drive and files on connected 
; removable media devices.

#3

Minor update (edit: and I lightly updated the first post to reflect this): markdown already has two separate ways to do italics (* and _), two separate ways to do bold, a few different unordered list markers, etc. Allow for a couple of different ways to do divs:

; --- {.outer}
; Lorem ipsum dolor sit amet, consectetur adipiscing
; elit, sed do eiusmod tempor incididunt ut labore et
; dolore magna aliqua. Ut enim ad minim veniam.
;
; ! --- {.inner}
; ! 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. Excepteur sint.
;
; occaecat cupidatat non proident, sunt in culpa qui
; officia deserunt mollit anim id est laborum.

Benefits:

  • makes it easier on the eyes when you’ve got nested divs

  • gives you prettier “caution/warning” divs ("!" instead of “;” for warnings/cautions/attentions):

      ! --- {.warning}
      ! Multiple div side-markers
      ! ahead. Keep your hands
      ! on the keyboard at all times.
    
  • allows for a convenient shorthand when you’ve only got a “{.foo}”:

      ! --- warning
      ! Multiple div side-markers
      ! ahead. Keep your hands
      ! on the keyboard at all times.
    

    That is, for simple cases, you can omit the curlies and the dot.


#4

Do you have a plan to disambiguate <hr> syntax?

; --- Example ---
; lorem ipsum
; ---
; dolor sit amet
; ---------------

#5

I don’t see any ambiguity there, zzzzBov. In your example, you’re using the side-marked syntax, so that means you’ve written “lorem ipsum”, an <hr>, “dolor sit amet”, and then another <hr>. The syntax is either side-marked or delimited, not both. Here’s the same thing, but using delimited syntax:

; --- example ---
lorem ipsum
---
dolor sit amet
---
; ---------------

(That’s two hr’s, one oddly at the end of the div.)

Incidentally, I like that your header has those trailing dashes. Looks good, and I think should be allowed/optional as well. edit: updated solution in initial post to reflect this


#6

I can’t help but wonder if…

<aside class="warning">
Keep your hands on the keyboard at all times.
</aside>

…would be clearer than some of the proposals that have been suggested. This syntax is just HTML and is already supported and works well with nested containers.

Warning boxes are also a kind of block, so it may be fine to override the existing block syntax and simply add a class, rather than inventing a new syntax. E.g.

> .warning 
> Keep your hands on the keyboard at all times.

> .spoiler 
> This is a spoiler.

A post-processing step could then add an additional markup required for rendering a warning box or a spoiler, but would fall back to a blockquote if that step isn’t available.


#7

except once you use <aside> you can’t use markdown within it. I recall reading a proposal to add attributes that enable markdown within HTML elements. I’m not against flagging elements as being markdown-enabled.


#8

@chrisalley, I think you may be conflating two separate problems:

  1. finding a syntax for <div>
  2. finding syntaxes for additional tags, for example, <aside>. (Like how we currently have “>” for <blockquote>s.)

My purpose here is the first.


#9

Given that CommonMark can be converted to formats other than HTML (PDF, etc), creating a syntax for <div> may be too specific. A div is a container element, so perhaps a syntax for “containers” is what is required here.

My points could be applied to containers in general (div, aside, or other); I’m essentially asking whether we need a special syntax just for containers or if existing syntax can be reused for specific use cases. We already have syntax for block quotes, code blocks, and potentially (via an extension) pre-formatted blocks - are there use cases that warrant another syntax that could not be solved by existing block syntax with classes?


#10

What’s under discussion is a syntax for a generic block container. Whether it always renders as a div in HTML, or could render as (say) an aside if certain attributes were set, is a separate issue. (And I’m inclined to think we should be as flexible as possible about how exactly the elements in the AST should be rendered.) And of course it would not be rendered as a div in, say, LaTeX. The term “div” here is being used just to mean “generic block container,” I think.

You’re right that block quotes already exist, and I’ve suggested in a few places that this could be our generic block container if there were a way to add attributes. (The container could default to a block quote if no attributes are specified, otherwise it would render as a div.) However, this suggestion hasn’t been popular for various reasons. People say that the association of this syntax with block quotes is too strong, and also that one might want to allow attributes to be attached to block quotes. There are also some who feel strongly that there should be a fenced generic block container (not just side-marked).


#11

A container doesn’t have a purpose until it’s decided what types of items should be placed inside the container.

By discussing generic container syntax in the abstract, there’s a risk that we’ll end up inventing something without an actual use case (that cannot be solved with other blocks).

I think warnings and spoilers can be considered special types of block quote. That is to say, I don’t think using the block quote syntax for these would be bending the association of the > syntax with block quotes too far.

Attributes could be added via consistent attribute syntax.

The main argument I’ve seen appears to be that we need a fenced block syntax. There’s an argument there, but I think it’s seperate from the argument that we need a generic container syntax. We can have one without the other.


#12

@jgm wrote:

What’s under discussion is a syntax for a generic block container.

Ah. A generic block container. I wasn’t thinking in terms of that. If you want it generic, you could use ; --- type-of-block {.styling #goes in="here"} (with curlies always required — just like with spans). Some examples:

Most-general syntax, here specifying a div (here with class="foo"):

; --- div {.foo}
; Lorem ipsum datsun pompom carfax ronco
; enzo corvette blowfish sockdrawer fob
; condor shoehorn pickle doorstop manwich.

without any styling:

; --- div
; Lorem ipsum datsun pompom carfax ronco
; enzo corvette blowfish sockdrawer fob
; condor shoehorn pickle doorstop manwich.

though, you wouldn’t write that that way, since you could instead just do:

; Lorem ipsum datsun pompom carfax ronco
; enzo corvette blowfish sockdrawer fob
; condor shoehorn pickle doorstop manwich.

Leaving out the block-type (and only supplying the styling) defaults to giving you a div:

; --- {.foo}
; Lorem ipsum datsun pompom carfax ronco
; enzo corvette blowfish sockdrawer fob
; condor shoehorn pickle doorstop manwich.

An html5 <aside> block, with class=“foo” and an extra helping of those handsome dashes:

; ------------ aside {.foo} --------------
; Lorem ipsum datsun pompom carfax ronco
; enzo corvette blowfish sockdrawer fob
; condor shoehorn pickle doorstop manwich.

and here with no styling:

; --------------- aside ------------------
; Lorem ipsum datsun pompom carfax ronco
; enzo corvette blowfish sockdrawer fob
; condor shoehorn pickle doorstop manwich.

Blockquotes:

; --- blockquote {.foo} ---
; Lorem ipsum datsun pompom carfax ronco
; enzo corvette blowfish sockdrawer fob
; condor shoehorn pickle doorstop manwich.

That works, but you’d likely much rather just write that instead using “markdown-native” syntax (">"):

> --- {.foo} ---
> Lorem ipsum datsun pompom carfax ronco
> enzo corvette blowfish sockdrawer fob
> condor shoehorn pickle doorstop manwich.

> Of course, blockquote
> with no styling.

Lineblocks — there’s no general block syntax because there’s no actual <lineblock> tag, but we’ve still got the specific “|” syntax:

| --- {.foo} ---
| Lorem ipsum datsun carfax
| ronco enzo corvette lomax

| And, of course, line
| block with no styling.

With this general syntax, you’d be giving up the shorthand syntax (where you could drop the curlies and the dot and write ; --- warning instead of ; --- {.warning}), but I think that’s probably reasonable, since it’s not that much of an extra readability cost to pay (and noting that divs simply aren’t going to be as seamless as blockquotes, code blocks, and line blocks, which have their own markdown native syntax and which are used all the time).


#13

@uvtc I didn’t have in mind adding an additional parameter for “block type.” Rather, the renderer could look at the div’s attributes (e.g. class) in deciding how to render it.

@chrisalley I’d personally be happy overloading block quotes. I’ve suggested this many times in various places, but there have always been strong opinions against it.

Advantages:

  • degrades nicely with existing Markdown renderers, which already do something sensible with blockquote syntax
  • works well with existing Markdown syntax highlighting
  • handles nesting well (because side-marked)
  • requires little change to parsers

Disadvantages:

  • some people think that > must render as a blockquote, even if it is specially marked with attributes
  • if we use blockquote syntax for block containers more generally, then we might lose a distinction between a block quote with attributes (say, author=“Einstein”) and a general container with those attributes.
  • no fenced form

#14

This is similar to the opinion that image syntax must render an image (rather than other media). I think the arguments discussed in the embedded audio and video topic can be applied here.


#15

@jgm wrote:

@chrisalley I’d personally be happy overloading block quotes.

Wait a sec. If you’d be ok with overloading blockquotes, why not instead overload the best side-marker of all, the pipe:

| --- {.foo #bar baz="moo"}
| One general block syntax
| to rule them all.

| ------------ foo -----------
| Shorthand for the simple
| case of `| --- {.foo}`.
| Extra dashes on either side
| are allowed.

| --------------------------
| Block with no particular
| styling (for html output,
| this would get you a plain
| div).

And of course,

| Unadorned, this still
| gets you a regular line
| block.

#16

Great minds think alike…

…although fools seldom differ.


#17

I think you dismiss the colon too quickly. It may not be a perfect horizontal delimiter, but it effectively functions both horizontally and vertically.

Fenced:

:::::::::::::::::::::::::: WARNING ::::::::::::::::::::::::::
            # rm -rf / – Deletes Everything! #

  The command rm -rf / deletes everything it possible can,
 including files on your hard drive and files on connected 
                 removable media devices. 
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

Side:

: {.warning}
:            # rm -rf / – Deletes Everything! #
:
:  The command rm -rf / deletes everything it possible can,
: including files on your hard drive and files on connected 
:                 removable media devices. 

Combined:

::::::::::::::::::::::::::: WARNING :::::::::::::::::::::::::::
::            # rm -rf / – Deletes Everything! #             ::
::                                                           ::
::  The command rm -rf / deletes everything it possible can, ::
:: including files on your hard drive and files on connected ::
::                 removable media devices.                  ::
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

All three are clean and clear, while using a single character.


#18

I have tried to explain this to non-programmers and the period, colon, or semicolon for a block syntax seemed easiest for them to understand. Not the pipe, as a table within a block would become unclear (in fenced syntax it looks like the start of a table, in side syntax it has unreadable double pipes).


#19

What do you think of:

  • staying with the symmetry of having both a side-marking
    as well as a fenced/delimited syntax,
  • keeping the requirement for the header dashes (to clearly
    signal that this is a block), and
  • allowing both the pipe and the colon?

That is, for side-marking, you could use:

| ------------- warning ---------------
| **`# rm -fr /`  deletes everything!**
|
| The command `rm -rf /` deletes
| everything it possibly can, including
| files on your hard drive and files on
| connected removable media devices.


: ------------- warning ---------------
: **`# rm -fr /` deletes everything!**
:
: The command `rm -rf /` deletes
: everything it possibly can, including
: files on your hard drive and files on
: connected removable media devices.

and for delimited syntax you could use:

|-------------- warning --------------
**`# rm -fr /`  deletes everything!**

The command `rm -rf /` deletes
everything it possibly can, including
files on your hard drive and files on
connected removable media devices.
|-------------------------------------


:-------------- warning --------------
**`# rm -fr /`  deletes everything!**

The command `rm -rf /` deletes
everything it possibly can, including
files on your hard drive and files on
connected removable media devices.
:-------------------------------------

#20

The greatest advantage of the colon is only one symbol for the whole thing. I prefer this one.

I don’t see any esthetical problems with the colon used horizontally. It is almost perfectly symetric in either directions and has a nice similarity to the equal sign in creating seamingly a doubled line. I guess that’s why @Trillinon used double colons to fence the box in the third example.

The colon could probably even be used to create a kind of shaded area (at least in monospaced font), because its dots are evenly spaced out. The vertical distance : is similar to the horizontal distance .. – so :: looks like the corners of a square. Thereby a line of colons looks like a shaded line, as does a vertical edge of double colons.

In the following example (of how i think a big button could look like in ascii style:) you can see how the shade effect looks like for areas:

::::::::::::::::::::::
::::::::::::::::::::::
::::::::: OK :::::::::
::::::::::::::::::::::
::::::::::::::::::::::

I think we could even allow any number of colons at the left and right edge of the box. It’s easy to trim them. So if someone wanted to have some shade in the box she could fill it with colons.

A similar effect could be created by using a spaced-out period symbol, but of course nobody would tediously type alternating period and spacebars.

. . . . . . . .
. . . . . . . .
. .  Cancel . .
. . . . . . . .
. . . . . . . .

To me the pipe is a little misleading (especially in combination with the dash) in making me instantly think about a table.

Would the initial line of dashed be needed every time or is it optional?

  • If it’s optional, then it doesn’t really hint towards how the syntax works for delimited cases.
  • If its obligatory, then it makes creating these boxes rather tedious again.