Sashmark / Blog

Markdown callouts: block quotes and pandoc fenced divs

Bobby Huang ·

The section Callouts in plain CommonMark holds a spec grep for callout syntax plus pandoc's commonmark output for a colon fence. Under A block quote with a bold label, two test files show the output for a quote that starts with a bold word. Reader flags that turned the colon fence into a div are in the section Fenced divs in pandoc. The section Classes and attributes on a div shows a class and a title passing through to the output. Numbered steps for writing a callout and checking what pandoc gave sit under Write a callout with a fenced div.

Key takeaways

  • Under Callouts in plain CommonMark, a spec search for callout syntax sits beside pandoc's commonmark output for a colon fence.
  • The section A block quote with a bold label shows pandoc's output for a one-line quote callout and a two-paragraph one.
  • The reader flags that gave a div element in this test are listed under Fenced divs in pandoc.
  • For fences inside fences, the section Nesting one div inside another shows two test files, one with more colons on the outer fence and one with three colons throughout, and what pandoc gave.
  • Cases where pandoc printed the colons as text are listed under When the colons stay as text.

You wanted a boxed note in your Markdown file, with a bold Warning label above the text. You typed three colons and a word, and pandoc handed the colons back inside a plain paragraph.

In this post, a markdown callout means a short note set apart from the text around it, with a label such as Note or Warning. Each pandoc result in this post comes from a single run of version 3.8.3 on a Mac. The tests cover two routes: a block quote with a bold label, and pandoc's fenced_divs extension. To repeat a run, rebuild a test file from its listing and use the command shown with it.

Callouts in plain CommonMark

Callout syntax is missing from CommonMark 0.31.2. A case-blind grep on the spec file for "callout" matched 0 lines. A grep for "admonition" also found 0, and a grep for three colons in a row found 0 too. For a control, the same kind of grep for "block quote" found 57. For the elements the spec does define, the syntax guide for core Markdown covers them.

The test file co-div.md held three lines:

::: note
Check the Doe Holdings totals.
:::

With pandoc -f commonmark -t html co-div.md, pandoc gave <p>::: note Check the Doe Holdings totals. :::</p>. The three lines ran together into one paragraph, colons and all.

A block quote with a bold label

The plain route runs on the commonmark reader as it is. Start the line with > and put the label in bold. For quote rules beyond this use, see the separate post on quotes and list nesting.

The test file co-quote.md held one line:

> **Note:** Check the Doe Holdings totals.

With pandoc -f commonmark -t html co-quote.md, pandoc gave a <blockquote> element holding <p><strong>Note:</strong> Check the Doe Holdings totals.</p>. The markdown reader matched it for this file.

A longer callout can hold two paragraphs. The test file cx-quote-two.md:

> **Warning:** Jane Doe signs last.
>
> Check the Doe Holdings totals first.

Under commonmark and under markdown, pandoc gave one <blockquote> with two paragraphs inside it, and the bold label sat in the first one. The line between them holds only >.

The <blockquote> tag in this output had no class attribute. The label was a <strong> element inside the first paragraph, so the word Warning is plain bold text in the HTML.

Fenced divs in pandoc

Pandoc names the colon syntax fenced_divs. Pandoc's extension list, in this test, showed +fenced_divs for its markdown reader and -fenced_divs for commonmark. So colon fences worked in markdown with no flag, while commonmark needed the flag added.

Run co-div.md through the markdown reader:

pandoc -f markdown -t html co-div.md

Pandoc gave this:

<div class="note">
<p>Check the Doe Holdings totals.</p>
</div>

To get a div from the commonmark reader, add +fenced_divs to its name. A run of pandoc -f commonmark+fenced_divs -t html co-div.md gave the same three lines.

Switching the extension off works the other way. The file cx-div-plain.md has the same shape as co-div.md, with shorter text. Its output under pandoc -f markdown-fenced_divs -t html cx-div-plain.md was <p>::: note Check the totals. :::</p>.

Markdown inside the fence was parsed as well. In cx-div-bold.md, the middle line was Check the **Doe Holdings** totals., and both markdown and commonmark+fenced_divs gave <p>Check the <strong>Doe Holdings</strong> totals.</p> inside the div.

The output lines had no style attribute. The word note showed up only as the class name on the <div> tag.

Classes and attributes on a div

Curly braces after the colons can hold a class plus other settings. The test file co-div-attr.md:

::: {.warning title="Heads up"}
Jane Doe signs last.
:::

With pandoc -f markdown -t html co-div-attr.md, pandoc gave <div class="warning" title="Heads up"> wrapped around <p>Jane Doe signs last.</p>. In the output, .warning became class="warning", and title="Heads up" stayed an attribute with the same name and value.

The commonmark+fenced_divs reader gave the same <div> line for this file. When the extension is left out, commonmark turned the whole file into one paragraph: <p>::: {.warning title="Heads up"} Jane Doe signs last. :::</p>.

Nesting one div inside another

The test file co-nest.md puts a div inside a div:

:::: outer
::: inner
Jane Doe
:::
::::

With markdown, and again with commonmark+fenced_divs, pandoc gave an outer div with an inner div inside it:

<div class="outer">
<div class="inner">
<p>Jane Doe</p>
</div>
</div>

This file gives the outer fence four colons and the inner fence three. That way you can tell by eye which closing line belongs to which div.

A second file, cx-nest-same.md, used three colons on its four fence lines. Under markdown, pandoc gave the same nested output as above. Plain commonmark printed co-nest.md as <p>:::: outer ::: inner Jane Doe ::: ::::</p>.

When the colons stay as text

These test cases gave a paragraph with the colons in it, and no <div> element.

  1. The commonmark reader on its own. The files co-div.md, co-div-attr.md and co-nest.md came out as one paragraph each, colons included.
  2. fenced_divs turned off. With markdown-fenced_divs, the file cx-div-plain.md gave <p>::: note Check the totals. :::</p>.
  3. No blank line above the fence, under markdown. The file cx-div-noblank.md puts the line Jane Doe wrote this. right above ::: note. What markdown produced was <p>Jane Doe wrote this. ::: note Check the totals. :::</p>. For the same file, commonmark+fenced_divs gave a paragraph and then a note div.

A missing closing fence went the other way. The file cx-div-open.md has an opening fence and one line of text, with no closing line. The markdown reader still gave a note div around the paragraph. It also printed a warning that the div was unclosed and was closing implicitly, and it exited with code 0.

Write a callout with a fenced div

  1. Pick the reader you'll run. In this test, markdown had fenced_divs on. With commonmark, add +fenced_divs to the reader name.
  2. Before the opening fence, add an empty line. The markdown reader needed it in this test.
  3. Type three colons, a space and a class name, such as ::: note. For more settings, put them in curly braces, such as ::: {.warning title="Heads up"}.
  4. Write the callout text on the lines below. Bold text inside was parsed in this test.
  5. Close with a line of colons. For a div inside a div, give the outer fence more colons so the pairs are easy to spot.
  6. Count the divs in the output. The pipe pandoc -f markdown -t html co-div.md | grep -c '<div' printed 1 here, while pandoc -f commonmark -t html co-div.md | grep -c '<div' printed 0.
  7. If the file must remain plain CommonMark, use a block quote with a bold label, as in co-quote.md.

Where Sashmark fits

The team is building Sashmark for editing the rendered page in place. The v1 plan pairs that with a Round-Trip kept clean, meant to leave untouched lines identical down to the byte. A Changes View sits in the plan too: it is planned to flag edits made after your previous read of a file, and the plan is for it to work without git. It is in development and has not been released. The app itself has no AI features. See the planned features, the help pages and the roadmap for where each part stands.

Progress updates will be posted on sashmark.com.

Questions

Does CommonMark have callout syntax?
A spec search and a commonmark test run are in the section Callouts in plain CommonMark.
What does pandoc do with a colon fence?
Reader flags and test output for colon fences are in the section Fenced divs in pandoc.
Why do the colons show up in my output?
Test files where pandoc printed the colons as text are under When the colons stay as text.
Can I add a title to a callout?
A title attribute in pandoc's output appears under Classes and attributes on a div.

What Sashmark plans for v1: Features · Roadmap

View as Markdown