Sashmark / Blog

Markdown blockquote not working after a paragraph

Bobby Huang ·

Both file listings and the bq-tight.md byte dump sit in Two files for the quote test. Results from the markdown run on the file lacking a blank line are quoted in One paragraph under the markdown reader. Under Three settings that split the lines, HTML from the remaining reader settings appears. Runs on the file holding an empty second line are quoted in When an empty line comes first. A spec passage with its example, plus an extension filter, is recorded in What the spec and the extension list say. Six steps built on pandoc, grep and od fill Find and fix a quote that stayed in the paragraph.

Key takeaways

  • The section One paragraph under the markdown reader shows pandoc's HTML and two grep counts for the file with no blank line.
  • Under Three settings that split the lines, you can read the commonmark command next to the HTML it printed.
  • HTML for the file holding an empty second line is quoted in When an empty line comes first.
  • The spec example and the extension filter cited for this test appear in What the spec and the extension list say.
  • Steps that run pandoc, grep and od against the two files make up Find and fix a quote that stayed in the paragraph.

A markdown blockquote not working, in this post, means a quote that pandoc folded into the paragraph above it, with the > marker left sitting in the sentence. Here, that happened under one pandoc reader setting when the marker line came straight below a sentence. After an empty line went in between, pandoc wrote a separate quote element under the four settings tried.

Each conversion happened once, on one Mac, with pandoc reporting version 3.8.3. The sections below report the HTML elements and characters pandoc wrote for two small files, and they stop at that output.

Two files for the quote test

Listing both files with line numbers through grep -n '' bq-tight.md bq-blank.md gave:

bq-tight.md:1:Jane Doe wrote this note.
bq-tight.md:2:> Ship the draft on Friday.
bq-blank.md:1:Jane Doe wrote this note.
bq-blank.md:2:
bq-blank.md:3:> Ship the draft on Friday.

The two files hold the same sentence and the same quoted line. In bq-tight.md, the > line follows the sentence directly. In bq-blank.md, an empty line 2 separates them.

A stray tab or a carriage return could change how a line parses, so this test looked at the raw bytes too. Running od -c bq-tight.md printed:

0000000    J   a   n   e       D   o   e       w   r   o   t   e       t
0000020    h   i   s       n   o   t   e   .  \n   >       S   h   i   p
0000040        t   h   e       d   r   a   f   t       o   n       F   r
0000060    i   d   a   y   .  \n
0000066

On the second row, the \n after note. is followed at once by > and then a space. No tab or carriage return appears in the dump, and a single \n separates note. from the marker.

Both files were converted to HTML four times, once per reader setting: markdown, markdown-blank_before_blockquote, commonmark and markdown_strict. In the second setting, the minus sign removes one extension from the markdown reader and leaves the rest of that reader alone.

One paragraph under the markdown reader

The command:

pandoc -f markdown -t html bq-tight.md

Output:

<p>Jane Doe wrote this note. &gt; Ship the draft on Friday.</p>

One p element came out, and no blockquote element did. Where the source had a line break, the output has a space. The marker came through as the entity &gt;, sitting mid-sentence just ahead of the word Ship.

Two tag counts confirm the reading. Piping that same run into grep -c '<blockquote>' printed 0. Piping it into grep -c '&gt;' printed 1, so the marker survived as text inside the paragraph.

In short, a > line typed directly beneath a sentence joined that sentence's paragraph under the markdown reader in this test.

Three settings that split the lines

For bq-tight.md, the remaining three settings wrote matching HTML. Here is the commonmark run:

pandoc -f commonmark -t html bq-tight.md

Output:

<p>Jane Doe wrote this note.</p>
<blockquote>
<p>Ship the draft on Friday.</p>
</blockquote>

The markdown-blank_before_blockquote and markdown_strict runs printed those same four lines. The sentence got a p element of its own. The quoted line went into a blockquote element that holds a second p. The marker no longer shows up in the output: grep -c '&gt;' printed 0 for both the commonmark run and the markdown-blank_before_blockquote run, and grep -c '<blockquote>' printed 1 for each.

The markdown-blank_before_blockquote result deserves a second look. It uses the same reader as the one-paragraph run, minus a single extension. Taking that one extension away was enough, in this test, to move the quoted line out of the paragraph and into its own element.

When an empty line comes first

The file bq-blank.md adds an empty line between the sentence and the marker. Pandoc gave this file identical HTML under the four settings:

<p>Jane Doe wrote this note.</p>
<blockquote>
<p>Ship the draft on Friday.</p>
</blockquote>

That list includes the markdown run, which had joined the two lines of bq-tight.md into one paragraph. For bq-blank.md, grep -c '<blockquote>' printed 1 under markdown, under markdown-blank_before_blockquote and under commonmark.

Here, adding a blank line split the text from the quote under every reader setting that was tried. Plain paragraphs and the blank lines between them get their own treatment in the paragraph spacing walkthrough. Headings run into a matching rule with that reader too; the post on a heading placed right after a paragraph has those tests.

What the spec and the extension list say

A name filter over the pandoc --list-extensions=markdown output kept one line, +blank_before_blockquote. The plus sign marks it as switched on for that reader. The same filter applied to pandoc --list-extensions=commonmark printed nothing for that name. The -blank_before_blockquote suffix changed the markdown output, as quoted under Three settings that split the lines.

On line 3687, the CommonMark text this test used (0.31.2) states that block quotes can interrupt paragraphs. Example 245, on lines 3691-3697, gives a two-line input shaped like bq-tight.md, with foo on one line and > bar on the next. Its expected HTML is a p element followed by a blockquote element. That pattern matches what the commonmark reader wrote for bq-tight.md here.

The markdown_strict run wrote the same HTML as commonmark. No reason for that match is offered here, since the runs do not show one.

The syntax of quotes themselves, quotes nested inside other quotes, and lines that carry on a quote without their own marker belong to the walkthrough on quote syntax and nesting.

Find and fix a quote that stayed in the paragraph

The steps below lean on these commands, run against the two test files:

grep -n '' bq-tight.md bq-blank.md
grep -n -B1 '^>' bq-tight.md bq-blank.md
od -c bq-tight.md
pandoc -f markdown -t html bq-tight.md | grep -c '<blockquote>'
pandoc -f markdown -t html bq-tight.md | grep -c '&gt;'
pandoc -f markdown -t html bq-blank.md | grep -c '<blockquote>'
pandoc -f markdown-blank_before_blockquote -t html bq-tight.md

Output of the second command:

bq-tight.md-1-Jane Doe wrote this note.
bq-tight.md:2:> Ship the draft on Friday.
--
bq-blank.md-2-
bq-blank.md:3:> Ship the draft on Friday.

When a quote ended up inside the paragraph above it, these six steps follow the runs quoted here.

  1. List marker lines with the line above each one. The second command put the sentence from line 1 of bq-tight.md above its marker line. In bq-blank.md, the line above the marker was line 2, and it was empty.
  2. Read the bytes between the two lines. In the od -c dump of bq-tight.md, a single \n sat between note. and >.
  3. Count quote elements in the HTML. For markdown runs, the <blockquote> count was 0 for bq-tight.md and 1 for bq-blank.md.
  4. Look for a leftover marker. For the markdown run on bq-tight.md, grep -c '&gt;' printed 1, which showed the > had stayed in the text.
  5. Separate the sentence from the > line by adding a blank one. That change produced a blockquote element under the four settings, as quoted under When an empty line comes first.
  6. Switch the reader setting when editing the file is off the table. Here, markdown-blank_before_blockquote, commonmark and markdown_strict each wrote a blockquote element for bq-tight.md.

Where Sashmark fits

If Sashmark's v1 comes out the way the plan describes, you could correct a phrase while the page reads formatted. Clean Round-Trip, listed among its planned parts, would then hand each untouched line back holding the bytes it had. Another listed part, the Changes View, aims to mark edits made after your most recent pass through the file, git unneeded.

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.

More at sashmark.com.

Questions

Why did my quote marker stay in the sentence?
For a marker line placed right under text, pandoc's HTML is quoted in One paragraph under the markdown reader.
Does commonmark want an empty line ahead of a quote?
The section Three settings that split the lines quotes what commonmark wrote for a file with no blank line.
Can I switch off blank_before_blockquote?
Runs that drop that extension appear in Three settings that split the lines. The extension filter sits in What the spec and the extension list say.
Which commands spot a quote that joined a paragraph?
Commands for finding marker lines and counting quote elements fill Find and fix a quote that stayed in the paragraph.

What Sashmark plans for v1: Features · Roadmap

View as Markdown