Sashmark / Blog

Markdown line blocks: pipe lines tested in pandoc

Bobby Huang ·

Spec search counts for the phrase line block sit under Line blocks and the CommonMark spec. The section Pipe lines in pandoc's markdown reader quotes the HTML pandoc wrote for a pipe test file. What the commonmark reader did with that same file appears under Pipe lines in plain commonmark. Hex bytes for an indented pipe line are listed in Leading spaces inside a line block. Output for a wrapped line is quoted under A long line that wraps. For a bare pipe between two names, see Blank lines from a bare pipe. Steps that include a grep check are numbered under Write a line block and check it.

Key takeaways

  • Under Line blocks and the CommonMark spec, spec searches for the phrase appear beside a control search.
  • The div and br output from pandoc is quoted in Pipe lines in pandoc's markdown reader.
  • A one-paragraph result and the error text from commonmark+line_blocks are quoted under Pipe lines in plain commonmark.
  • Hex bytes for the indent on a pipe line are listed under Leading spaces inside a line block.
  • Under Blank lines from a bare pipe, pandoc output is quoted for a pipe with nothing after it.

Say you put a name and an address on three lines, started every line with a pipe, and wanted three lines back. What came out depends on the reader you ran.

This post looks at markdown line blocks: pipe-led lines that pandoc can keep apart in its output. Everything below came out of a pandoc session on macOS (version 3.8.3), with the test file named beside its result, so anyone can rerun it. Pandoc wrote HTML in these tests; how a viewer shows that HTML was never checked here.

Line blocks and the CommonMark spec

CommonMark's spec has nothing named a line block. The copy searched here was version 0.31.2. Grepping the spec text for line block, ignoring case, returned 0. Swapping in line_block or line-block gave 0 too. A control search for block quote returned 57, so the search itself worked.

The rule that does apply is the one for paragraphs, at spec lines 3276 to 3281. Consecutive non-blank lines that fit no other block type make a paragraph, and its raw content is those lines concatenated, minus initial and final spaces or tabs. Under that rule, a leading pipe is just a character in paragraph text. The post on blank lines and paragraphs explains that rule.

Pipe lines in pandoc's markdown reader

Pandoc calls the pipe syntax line_blocks. When this run listed the markdown extensions, +line_blocks was there, so the extension needed no flag.

The test file lb-basic.md holds three pipe lines:

| Jane Doe
| 1 Doe Street
|     Suite 2

The command:

pandoc -f markdown -t html lb-basic.md

Pandoc wrapped the three lines in a single div with the class line-block and put a <br /> tag after the first two. Here is that output, ASCII-normalized: in the real output, the four spaces before Suite 2 are four U+00A0 no-break space characters.

<div class="line-block">Jane Doe<br />
1 Doe Street<br />
    Suite 2</div>

In this test, inline marks worked inside a line. The file lb-inline.md held the lines | **Jane** Doe and | 1 Doe Street. The markdown reader turned them into this:

<div class="line-block"><strong>Jane</strong> Doe<br />
1 Doe Street</div>

Pipe lines in plain commonmark

Feed that same lb-basic.md file to the commonmark reader:

pandoc -f commonmark -t html lb-basic.md

The result was a single paragraph: <p>| Jane Doe | 1 Doe Street | Suite 2</p>. The pipes stayed as text and the three lines were joined. The five spaces between the third pipe and Suite 2 came out as one.

Turning the extension off had the same effect on the markdown reader. That one paragraph showed up again with pandoc -f markdown-line_blocks -t html lb-basic.md.

Pandoc refused to switch the extension on for commonmark. A grep for line_blocks in the commonmark extension listing counted 0, and the markdown listing counted 1. An attempt with pandoc -f commonmark+line_blocks -t html lb-basic.md exited with code 23 and printed this:

The extension line_blocks is not supported for commonmark.
Use --list-extensions=commonmark to list supported extensions.

Hard breaks are a separate way to keep lines apart inside a paragraph, and the post on hard line breaks covers them.

Leading spaces inside a line block

In lb-basic.md, the third line is a pipe, five spaces, then Suite 2. Four of those five spaces survived in the markdown reader's output, written as U+00A0 characters in place of plain spaces.

Two checks in the extra test log show it. This pipe counts output lines that hold a byte outside printable ASCII:

pandoc -f markdown -t html lb-basic.md | LC_ALL=C grep -c '[^ -~]'

It printed 1. The hex bytes of the third output line began with the pair c2 a0 four times, then 53 75 69 74 65 for the letters of Suite. The pair c2 a0 is how UTF-8 stores U+00A0.

So the indent came through as characters that differ from the plain spaces in the source file. The source line itself held only ASCII spaces.

A long line that wraps

The file lb-continue.md has a pipe line, then a line opening with two spaces and no pipe, then a second pipe line:

| The first line runs long
  and wraps onto a second line
| Then a new line

Under pandoc -f markdown -t html lb-continue.md, the indented line merged into the pipe line above it:

<div class="line-block">The first line runs long and wraps onto a second
line<br />
Then a new line</div>

The output held one <br /> tag, after the merged text. The file had three lines and the block came out as two. The line ending after second in that output carries no <br /> tag.

Blank lines from a bare pipe

The file lb-blank.md puts a bare pipe between two names:

| Jane Doe
|
| Doe Holdings

Here is what the markdown reader wrote:

<div class="line-block">Jane Doe<br />
<br />
Doe Holdings</div>

The bare pipe became an empty line with a <br /> tag of its own, and the three lines stayed inside one div.

Write a line block and check it

The steps that follow rely on the markdown reader, since commonmark refused the extension in this run.

  1. Run pandoc with -f markdown. In this test it had +line_blocks with no flag added.
  2. Start each line with a pipe and a space, for example | Jane Doe.
  3. For an indent, add spaces after that first space. Here they came out as U+00A0 characters.
  4. For an empty line, type a bare | on its own line.
  5. To join a long line onto the one above, start the next line with two spaces and no pipe, as in lb-continue.md.
  6. Check the output with grep:
pandoc -f markdown -t html lb-basic.md | grep -c 'line-block'

That printed 1 in this run. Swapping the reader to commonmark made it print 0.

  1. A 0 means no line holding line-block was written; check which reader the command names.

Where Sashmark fits

For v1, Sashmark plans in-place editing where the page renders, and the plan wants the Round-Trip clean, so the bytes of lines you skip would stay as they were. A planned Changes View would flag what's different since your prior reading, and no git would be required under the plan. 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.

sashmark.com

Questions

What is a line block in Markdown?
Pandoc's div output for a three-line pipe file is quoted in Pipe lines in pandoc's markdown reader.
Why did my pipe lines merge into one line?
Under Pipe lines in plain commonmark, the single paragraph from the commonmark reader is quoted.
Can a line block hold an empty line?
For the output of a bare pipe between two names, see Blank lines from a bare pipe.
How can I check that pandoc made a line block?
A grep count on pandoc output appears in the steps under Write a line block and check it.

What Sashmark plans for v1: Features · Roadmap

View as Markdown