Certain info strings on fenced code blocks break formatting between the blocks

I just encountered a bug while I was writing a post on a Discourse-powered forum and would like to report it.

It seems like if I have two fenced code blocks with an info string of “{.cpp}”, where each block starts with a line equal to “```{.cpp}” and ends with a line equal to “```”, then any text formatting between the two blocks of code does not work at all, and we see the markup instead of seeing nicely-formatted text. See below for an example:

// Here is a block of C++ code.

For some reason we cannot have monospace, italic, bold, or link text in this paragraph, which is between two blocks of C++ code. In fact, I can’t find any other Markdown, BBCode, or HTML that does work in this area.

We can’t even have multiple paragraphs.

// Here is a second block of C++ code.

A workaround for this is to remove the {.cpp} info string on the first code block, but of course that destroys the code highlighting in that first block. I couldn’t find any better solution even though I tried info strings of “.cpp”, “cpp”, and “c++”.

I made a copy of this post as a Gist so you can see the markup I used and verify that it works correctly in GitHub-flavored Markdown.

–David

2 Likes

Why are you putting the language inside curly brackets? This isn’t necessary (I don’t think it’s even correct) and might be part of your problem.

1 Like

I think you are misusing the language hint, at least as it is designed here

/* I love to c */

Under the sea

/* with a virtual destructor */
```cpp
/* I love to c */
```

Under the **sea**

```cpp
/* with a virtual destructor */
```

```{.cpp} is not something our parser even looks for.

1 Like

Hi @codinghorror! I’m not sure, but I think I started using info strings like {.cpp} several years ago because the Doxygen manual’s section about markdown support has examples of fenced code blocks that show it that way.

Before starting this topic, I tried to look around for Discourse documentation or documentation on http://commonmark.org/ that would tell me what the correct info string is for C++, but I couldn’t find the right documentation. So I tried to guess what the info string might be. When I changed the info string from “{.cpp}” to “cpp”, I saw that class names in my example code ceased to be highlighted, so I thought that “cpp” wasn’t correct. However, since @sam says that “cpp” is correct then I suppose it is. Thanks, @sam!

// If we use no info string or {.cpp}, the class name gets highlighted.
// I'm not sure what language Discourse has guessed here.
class Example {
  void foo();
  virtual ~Example();
};
// If we use "cpp", the class name is not highlighted. 
class Example {
  void foo();
  virtual ~Example();
};

So, practically, this problem is solved. :slight_smile:

However, isn’t it fair to say that my original post is rendered incorrectly by Discourse? The paragraph I tried to put between the two code blocks is not formatted as code and it’s not formatted as normal text, so that seems weird to me. The CommonMark Spec 0.24 defines info strings like this:

The line with the opening code fence may optionally contain some text following the code fence; this is trimmed of leading and trailing spaces and called the info string. The info string may not contain any backtick characters. (The reason for this restriction is that otherwise some inline code would be incorrectly interpreted as the beginning of a fenced code block.)

The first word of the info string is typically used to specify the language of the code sample, and rendered in the class attribute of the code tag. However, this spec does not mandate any particular treatment of the info string.

I don’t really see why an info string with period or bracket characters should affect other paragraphs in the document that are outside of the fenced code block and make them render in a weird way. An info string with periods and brackets seems to be an acceptable part of Markdown, or am I missing something?

I will close this for now and put the markdown-it review tag on it.

We have plans afoot to move to a compliant CommonMark engine, when we move to it we can test this particular variation does not cause the engine to do funny things.

3 Likes