We should abandon indented code blocks

I was thinking about starting this anyway, but then I saw this was listed as an appropriate topic in the pinned feedback thread. :slight_smile:

It’s a big change, but Standard Markdown would be immeasurably helped by abandoning indented code blocks. They’re a terrible, inconsistent part of the original Markdown, which causes problems throughout the rest of the language, and fenced code blocks are better in every way.

For one, indented code blocks mean that you’re never allowed to indent markdown for any reason, which is pretty limiting. I’m a CSS spec author, and write my specs with a processing tool called Bikeshed, which partially supports Markdown. It’s common convention in Bikeshedded specs to only write headings against the margin, and indent everything else, as it makes it easier to quickly skim through a big source file and see where the sections are. Here’s an example source file.

For two, indented blocks make handling Markdown nested in HTML much more difficult. Bikeshed supports intermixed HTML by detecting lines that start with a block tag, and outputting just that line literally; the very next line can be (indented) markdown text again. I suspect the reason SMD has the slightly odd rules about HTML blocks is to avoid accidentally triggering code blocks from the indentation. Bikeshedded specs regularly put Markdown text on the very next line after an HTML tag, and it looks completely natural, so this is a place where I’m currently going to have to willfully violate the spec.

For three, the handling of indented code blocks within lists is crazy town - having to indent 8 spaces makes it look terrible.

For four, blank lines in code blocks are hard to see/express. Plus, some editors have options to auto-remove trailling whitespace from a line (I use this, to reduce spurious diff churn). (On that note, I’m glad to see a way to force hard breaks without trailing whitespace make its way into SMD.)

Overall, if indented code blocks go away, Markdown can become completely indentation-agnostic, where the only real requirement is that following lines in a block have to be indented at least as much as the first line. That’s basically what I’ve implemented in Bikeshed so far, and I plan to continue supporting precisely that, even if I match SMD everywhere else.

7 Likes

I understand the reasons, but I feel this is too big a change to the core.

Note that most non trivial code in the wild tends to be “naturally” indented by 4 spaces or more, which is why the average Java coder on Stack Overflow got good results just pasting in a random block of code into a question. I think this is the rationale that was used to select this convention in the first place but I am only guessing.

I agree that fenced code blocks are better in a lot of ways, but they aren’t a replacement, for one thing, sometimes you just want a non syntax highlighted preformatted block versus fenced code blocks which I see as explicit references to “source code”.

Yeah, I suspected this would be the answer. It doesn’t kill me, it just means I’ll have to willfully violate SMD to continue to support idiomatic use of my own tool. Ah well.

How about non java coder? So many language out there. And they have all different convention for indent. How about terminal command output? Log?

Even if it is java, you should indent all line by only one unindented line.

Moreover, it is too hard to indent properly for average joe.

“You should use code block for this.”

“How?”

“Copy and paste into your editor. Select all then indent. Copy and paste here”

“I cannot find indent in my editor. I’m using notepad.”

"Forget about it. Just wrap around the block with ```’

On Stack Overflow (and here) code can be indented by highlighting and using the keyboard shortcut ctrl+k, or the clicking the “code” button ( {} on Stack Overflow, </> here). This is not the case on github (although it does respect indentation for code blocks).

The benefit of ``` IMO is that you can specify the language more concisely.

Addressing some of @tabatkins original points (standardizing code indenting means that it is very hard or impossible to indent for other reasons) and borrowing a bit from his point #2 - what if there was a an negative indicator that could be used in the first line of an indent block to indicate that it should not be treated as code? For example, starting off the top line with at least four dashes (or equal signs, or pluses, or something) would mean that that line should not be processed as Markdown.

I like this idea, but I would say it will break too many existing documents, maybe better implement this as extension or it’s too much change for extension ?

1 Like

The nice thing about indented codeblocks is that they’re very easily read in the Markdown source, easier then fenced blocks. Fenced blocks have their own advantages, but indented blocks win in the original “readable as plain text” category.

For your point two, SMD makes mixing Markdown and verbatim HTML much nicer than the original “spec”.

For your point three, I don’t understand why indenting the code block 4 spaces from wherever the current margin of the text is would look terrible. This seems like the most natural thing to do:

27. We propose frobbling the quux as shown in the
    following pseudocode section:

        while (ad nauseam) {
            x := foo(bar)
        }
        result = baz(x)

    The performance characteristics of this code
    are, to use the industry standard term, awesome.

For your point four, again I don’t understand. How are blank lines in code blocks “hard to see/express”? They’re just… blank lines. And the part about trailing whitespace doesn’t even apply to code blocks, because in codeblocks a linebreak in the source is a linebreak in the rendered version.

7 Likes

I gotta go with @balpha on this one. Readability (and to a lesser degree writability) should take precedence over ease of implementation.

I have a sneaking suspicion issues with indented code blocks stem from the lack of tab-key indenting in most web based editors.

I agree that this project (now “Common Markdown”?) should not be departing from but only refining, clarifying, tightening up the original syntax.

However when the time comes to address extensibility, any mechanism should include the ability to disable, modify, and/or substitute core behavior as well as add to it.

So a given extension could say “use this for code blocks rather than the core’s leading-whitespace”.

Of course the extension would need to spec what to do with the leading-whitespace (leave/ignore? strip it out?)

And the result will likely vary by the conversion’s target syntax.

For your point three, I don’t understand why indenting the code block 4 spaces from wherever the current margin of the text is would look terrible.

This is no longer true in SMD, but in Gruber’s Markdown, you don’t need to indent subsequent lines of an initial paragraph in a list item. The following is valid:

27. We propose frobbling the quux as shown in the
following pseudocode section:

If you’re using that convention, some code showing up indented 8 spaces suddenly is a bit striking/surprising.

For your point four, again I don’t understand. How are blank lines in code blocks “hard to see/express”? They’re just… blank lines. And the part about trailing whitespace doesn’t even apply to code blocks, because in codeblocks a linebreak in the source is a linebreak in the rendered version.

This might have been me having a broken understanding of how MD treated blank lines between indented blocks. Per the spec, I see that indented blocks separated by blank lines are condensed into one, with the blank lines preserved. I had assumed you had to indent the blank lines as well, which means invisible line-ending whitespace would be significant.

(This just makes me dislike indented code blocks for another reason - it’s impossible to have two separate indented code blocks follow each other. The “two blank lines closes everything” rule doesn’t apply here. You have to put in some other construct between them, like an HR, to make them properly separate.)

I have a sneaking suspicion issues with indented code blocks stem from the lack of tab-key indenting in most web based editors.

This is certainly why I hate Markdowns that only allow indented code blocks; as long as fenced code blocks exist, though, it’s not a big deal.


Anyway, as I said, I agree with the reasoning; as a web spec author, I completely understand the role that back-compat plays in writing a good spec. This’ll just be one of the few places where I’ll have to document a willful violation of the standard in one of my own tools, something I was already prepared to do. My blog system, on the other hand, should be able to follow the spec perfectly, which makes me happy.

Larger list of syntax duplications which I think should also be deprecated from the language and later removed: https://github.com/karlcow/markdown-testsuite/issues/53 . Analogous for italics: "_" and "*" being synonymous is redundant and confusing

I couldn’t agree with @tabatkins more. The indent rule is really a handful of rules that all pertain to indentation:

  • 4 leading spaces is an indent
  • 0-3 leading spaces are arbitrary formatting
  • Indented code can not interrupt a paragraph

These rules (that strangely resemble the rules for the Monty Python Holy Hand Grenade) create a number of oddities and complexities:

  1. Sublists indentation where not enough M + N spaces have been used (instead of simply left or right aligning list items). Example: Sublist indentation

  2. Looks like a duck but not a duck, indented code block following a paragraph:
    Examples: Paragraph followed by not-a-code-block OR List item followed by code block

  3. Then there are things like the following examples:
    A. A simple nested list
    B. Same list simply put in a a block quote is no longer nested
    C. Looks almost the same as the last, but I added a space so now its nested again

    D. Looks like its part of the list in the block quote because it lines up, but its not part of the list
    E. Now it is because I added a space and misaligned it
    F. This gives the same result as the previous
    G. But add a space and you get a code block followed by a paragraph that isn’t in the list item

And I understand the backwards compatibility argument on this one. But this whole indentation ruleset allows for subtle, nearly indiscernible differences in source to have wildly different results. That is bad for readability, writability, and implementation.

The other frustrating part of the indent rules comes into play in other writing forms:

  • Paragraph indentations yield codeblocks
  • Indent structured documents
  • Poetry, lyrics and such. Though one could make the argument that such structured text belongs in a preformatted block anyway, it is still worth mentioning.

I guess the bottom line is, programmers aren’t the only ones who hit the tab key and the rules surrounding what indents work how and where is just confusing… even worse if you do any copy and paste.

Although the fenced code blocks are easier to write, from a readability standpoint indented code blocks look great. If you have the time to craft your Markdown document to be visually appealing it is beneficial to use indented code blocks.

As with Setext vs Atx style headers you have a choice. The Setext style headers are less convenient to type but are visually closer to conventional headings.

2 Likes

I completely agree that code blocks look better indented. I just think that a lot of other types of blocks look good indented as well. Indentation shows hierarchy visually better than any other construct. If indented code blocks did not exist at all, indentation would be arbitrary formatting. Any block, including fenced code blocks could be indented as much as needed to improve readability.

2 Likes

On Stack Overflow and other Stack Exchange sites, the answer is even simpler: select all and press Ctrl+K.