---
title: "YAML front matter multiline string: three forms in pandoc"
slug: yaml-front-matter-multiline-string
excerpt: "Under Template output from three readers, pandoc's HTML for a yaml front matter multiline string is quoted from the test log."
quickAnswer: "Input lines, the template and the commands sit under The test file with three header values. Under Template output from three readers, the HTML lines pandoc printed are copied from the log. Pandoc's native lines sit under Native output for keep, fold and plain. A second test file and its runs appear under An empty line within the value. The header run without yaml_metadata_block is quoted in full under Plain commonmark with the extension off. Line numbers from pandoc's extension lists are cited under Checking the three extension lists. Numbered steps for repeating the runs are laid out under Running the commands yourself."
keyTakeaways:
  - "For the HTML pandoc wrote, see Template output from three readers."
  - "Look under Native output for keep, fold and plain for the tree lines quoted from the log."
  - "Under An empty line within the value, a second test file and its output are shown."
  - "Turn to Checking the three extension lists for the cited lines and a control run."
  - "The section Running the commands yourself gives numbered steps with the pandoc lines to type."
publishedDate: 2026-10-21
dateModified: 2026-10-21
author: Bobby Huang
cluster: B
role: post
status: published
faq:
  - q: "Does a value written after | keep its line break?"
    a: "Compare your file with the tree lines quoted under Native output for keep, fold and plain."
  - q: "What happens to an empty line inside a > value?"
    a: "The runs for that file are reported in An empty line within the value."
  - q: Why did my header come out as a heading?
    a: "Check your reader against the run in Plain commonmark with the extension off."
  - q: Which pandoc readers have yaml_metadata_block switched on?
    a: "Pandoc's list lines are cited in Checking the three extension lists."
related:
  - yaml-front-matter-in-markdown
  - yaml-front-matter-quoting
  - what-is-front-matter
---

As used here, a yaml front matter multiline string is a header value typed across two or more lines of the file. I wrote one such value three ways: after `keep: |`, after `fold: >`, and as a plain value whose second line is indented under the key. Here, yaml block scalar front matter means the first two of those, the forms opened by a `|` or a `>`.

On one Mac, I fed the test file to pandoc, whose version line said 3.8.3, under `markdown`, `commonmark+yaml_metadata_block` and `commonmark_x`, plus one run with plain `commonmark`. I copied each result from the test log and kept pandoc's line breaks where it put them. How an app or a site shows a header value was never part of the test. For a primer first, read [the guide to Markdown headers written in YAML](yaml-front-matter-in-markdown.md).

## The test file with three header values

The input is `multiline.md`. The log gives it a line count of 13:

```markdown
---
title: Doe plan
keep: |
  Jane Doe owns step one.
  John Doe owns step two.
fold: >
  Jane Doe owns step one.
  John Doe owns step two.
plain: Jane Doe owns step one.
  John Doe owns step two.
---

Body line.
```

The header holds four keys. `title` is a short value on one line. `keep` and `fold` hold the same two sentences, one under a `|` and one under a `>`. The value of `plain` begins on the key line and carries on to an indented second line. For the separate question of when a header value needs quote marks, see [the guide to quoting YAML values](yaml-front-matter-quoting.md).

To print the three values, the runs used a pandoc template, `multiline-tpl.html`:

```text
keep=[$keep$]
fold=[$fold$]
plain=[$plain$]
```

In a pandoc template, a key name between dollar signs prints that key's value. The square brackets are literal characters in that file; they mark where a value starts and stops in the output.

These are the three commands, one per reader:

```sh
pandoc -f markdown -s --template multiline-tpl.html -t html multiline.md
pandoc -f commonmark+yaml_metadata_block -s --template multiline-tpl.html -t html multiline.md
pandoc -f commonmark_x -s --template multiline-tpl.html -t html multiline.md
```

In the log, `rc=0` follows the output of these three runs.

## Template output from three readers

These lines came out under `markdown`:

```text
keep=[<p>Jane Doe owns step one. John Doe owns step two.</p>]
fold=[<p>Jane Doe owns step one. John Doe owns step two.</p>]
plain=[Jane Doe owns step one. John Doe owns step two.]
```

Byte for byte, the `commonmark+yaml_metadata_block` run repeated those three lines, as did the `commonmark_x` run.

Under these three readers, pandoc wrapped the `keep` value in a `<p>` element and did the same for `fold`. The `plain` value came back as bare words with no tag around them. In the HTML, `keep` puts its two sentences on one line, split by a single space, and `fold` does too. Going by the HTML alone, you can't tell the `|` value apart from the `>` value. The native runs below show where they part.

## Native output for keep, fold and plain

The extra script asked pandoc for its native format, a text dump of the document tree that includes the header:

```sh
pandoc -f markdown -s -t native multiline.md
pandoc -f commonmark+yaml_metadata_block -s -t native multiline.md
pandoc -f commonmark_x -s -t native multiline.md
```

Pandoc returned rc 0 for these three native runs. The dump is long, so I quote only the lines that matter, taken from the `markdown` run. The `keep` entry opens like this:

```text
          , ( "keep"
            , MetaBlocks
                [ Para
```

Further down that entry, the first sentence meets the second here:

```text
                    , Str "one."
                    , SoftBreak
                    , Str "John"
```

The `fold` entry in that run is also a `MetaBlocks` holding a `Para`. At the same join, it has a `Space`:

```text
                    , Str "one."
                    , Space
                    , Str "John"
```

The `plain` entry is a `MetaInlines` list, with no `Para` around the words:

```text
          , ( "plain"
            , MetaInlines
                [ Str "Jane"
```

At its join, `plain` also has a `Space` between `Str "one."` and `Str "John"`.

The `commonmark+yaml_metadata_block` dump and the `commonmark_x` dump match on these points. Both put a `SoftBreak` at the join in `keep`, at log lines 174 and 259, and a `Space` at the join in `fold`, at lines 149 and 234. For `plain`, both show `MetaInlines` and a `Space` at the join.

So the `|` value held a `SoftBreak` between its two sentences, and the `>` value held a `Space` in that spot. Across the three readers, the two values typed `MetaBlocks` are the two that came back inside `<p>` tags in the template output, and the one typed `MetaInlines` came back without a tag.

## An empty line within the value

A second file, `multiline-blank.md`, drops the `plain` key and inserts one empty line partway through `keep` and partway through `fold`, splitting the two sentences. Its count in the log is also 13 lines:

```markdown
---
title: Doe plan
keep: |
  Jane Doe owns step one.

  John Doe owns step two.
fold: >
  Jane Doe owns step one.

  John Doe owns step two.
---

Body line.
```

Its template, `multiline-blank-tpl.html`, prints two values:

```text
keep=[$keep$]
fold=[$fold$]
```

The commands follow the same pattern as before:

```sh
pandoc -f markdown -s --template multiline-blank-tpl.html -t html multiline-blank.md
pandoc -f commonmark+yaml_metadata_block -s --template multiline-blank-tpl.html -t html multiline-blank.md
pandoc -f commonmark_x -s --template multiline-blank-tpl.html -t html multiline-blank.md
```

Pandoc wrote this for `markdown`:

```text
keep=[<p>Jane Doe owns step one.</p>
<p>John Doe owns step two.</p>]
fold=[<p>Jane Doe owns step one. John Doe owns step two.</p>]
```

Output from `commonmark+yaml_metadata_block` and from `commonmark_x` matched it line for line, and pandoc returned rc 0 each time. So the gap turned the `|` value into two `<p>` elements in this test, while the `>` value stayed a single `<p>` with both sentences inside.

## Plain commonmark with the extension off

One run in the first script read `multiline.md` with the plain `commonmark` reader and no extension added:

```sh
pandoc -f commonmark -t html multiline.md
```

With plain `commonmark`, pandoc wrote an `<hr />` line, then one `<h2>` element holding the header text, then the body paragraph, and exited with rc 0:

```html
<hr />
<h2>title: Doe plan keep: | Jane Doe owns step one. John Doe owns step
two. fold: &gt; Jane Doe owns step one. John Doe owns step two. plain:
Jane Doe owns step one. John Doe owns step two.</h2>
<p>Body line.</p>
```

Inside that plain `commonmark` `<h2>`, keys and values run together as ordinary words. In the plain `commonmark` heading, the `|` is still there as typed, and the `>` came out as `&gt;`. That plain `commonmark` heading spans three output lines, and those breaks fall at other points than the line breaks in the input file.

## Checking the three extension lists

Pandoc's extension lists for the three readers were saved from the same 3.8.3 build, one file per reader. I searched those files for `yaml_metadata_block`:

1. For `markdown`, line 73 of the list says `+yaml_metadata_block`.
2. For `commonmark`, line 30 of the list says `-yaml_metadata_block`.
3. For `commonmark_x`, line 30 of the list says `+yaml_metadata_block`.

In these files, a plus before a name marks an extension the reader turns on by default, and a minus marks one it leaves off by default. That fits the runs: `commonmark+yaml_metadata_block` printed the three values through the template, and plain `commonmark` printed the `<h2>` you saw above.

The first script also ran a control, to show that pandoc checks extension names. With `commonmark+bogus_ext` as the reader, it stopped with rc 23 and printed `The extension bogus_ext is not supported for commonmark.` on its first line.

## Running the commands yourself

The commands below give bare file names, so work inside the directory where you saved the files.

1. Save `multiline.md` and `multiline-tpl.html` with the lines shown under The test file with three header values.
2. For the template output, type `pandoc -f markdown -s --template multiline-tpl.html -t html multiline.md`, then the two other readers, and compare what you get with Template output from three readers.
3. For the tree dump, type `pandoc -f markdown -s -t native multiline.md` and find the `keep` entry. Look for `SoftBreak` after `Str "one."`.
4. Save `multiline-blank.md` and `multiline-blank-tpl.html`, then type `pandoc -f markdown -s --template multiline-blank-tpl.html -t html multiline-blank.md` and count the `<p>` tags in the `keep` value.
5. Last, repeat the one command shown under Plain commonmark with the extension off, then look at the header lines.

I ran a single pass under 3.8.3 and tried no other pandoc version. For keys set inside other keys, read the sibling post on [nested keys in YAML front matter](yaml-front-matter-nested-keys.md).

## Where Sashmark fits

You can't get Sashmark yet; its builders are still putting the desktop app together. The plan for its Round-Trip feature is easy to state: change one word in the formatted text, and the saved file should differ by that word and not one byte more. Its Changes View idea is to put a mark beside every stretch an agent redid since your previous visit, git repo or plain folder.

It is in development and has not been released. The app itself has no AI features. See the [planned features](/features), the [help pages](/help) and the [roadmap](/roadmap) for where each part stands.

More at [sashmark.com](https://www.sashmark.com/).
