---
title: "Markdown image in table cells: pandoc output compared"
slug: markdown-image-in-table
excerpt: "Quoted HTML for a markdown image in table cells, run under one reader, sits in Markdown reader run."
quickAnswer: "Under Two input files, both inputs are shown as cat printed them. For the image table, what the markdown reader printed is quoted in Markdown reader run. Look in Plain commonmark run for that file under plain commonmark. For the pipe_tables extension added to commonmark, see Run under commonmark+pipe_tables. Size block output is compared in A width attribute after the image. Alt text holding a pipe gets its runs in A pipe character inside alt text. Numbered grep steps for saved output are in Counting tables with grep."
keyTakeaways:
  - "Both test inputs, as cat printed them, sit in Two input files."
  - "See Markdown reader run for the HTML that reader wrote for the image table."
  - "What plain commonmark printed for that file sits in the section Plain commonmark run."
  - "Size block results from two table readers are compared in A width attribute after the image."
  - "Steps for counting tables in saved output are numbered in Counting tables with grep."
publishedDate: 2026-10-21
dateModified: 2026-10-21
author: Bobby Huang
cluster: B
role: post
status: published
faq:
  - q: My image table turned into one paragraph. Why?
    a: "That output, with the extension list line beside it, appears in Plain commonmark run."
  - q: Can I set an image width inside a table cell?
    a: "Under A width attribute after the image, the runs for that size block are quoted."
  - q: Can alt text inside a table hold a pipe?
    a: "Two rows, one bare and one escaped, are run in A pipe character inside alt text."
  - q: Which grep counts show a missing table?
    a: "Grep counts on saved output are numbered in Counting tables with grep."
related:
  - markdown-tables
  - markdown-images
  - markdown-image-size
---

Pandoc turned a markdown image in table cells into three shapes during this test, one per reader setting. Pandoc's `markdown` reader and its `commonmark+pipe_tables` setting each placed the image in an `<img>` inside a `<td>`; plain `commonmark` produced a lone paragraph with the pipes still in it.

The pandoc build on the one Mac that ran these conversions was 3.8.3. What follows sticks to the HTML that pandoc printed. For pipe rules, delimiter rows and alignment, read [Markdown tables](markdown-tables.md). Image syntax has its own page, [Markdown images](markdown-images.md), and size syntax is covered in [image size](markdown-image-size.md).

## Two input files

The test folder starts with two short inputs. The command `cat img-table.md` showed a two-column table that pairs a text cell with an image cell on each row:

```text
| Item | Photo |
|---|---|
| Desk | ![Doe desk](desk.png) |
| Chair | ![Doe chair](chair.png){width=50%} |
```

On the Chair row, `{width=50%}` comes straight after the image, touching its closing parenthesis.

The second file came back from `cat img-table-pipe-alt.md` like this:

```text
| Item | Photo |
|---|---|
| Desk | ![Doe | desk](desk.png) |
| Lamp | ![Doe \| lamp](lamp.png) |
```

The Desk row puts a bare `|` inside the alt text. The Lamp row writes it as `\|`, with a backslash in front.

Both files went through `-f markdown`, `-f commonmark` and `-f commonmark+pipe_tables`, each time with `-t html`. An extra script then added two more files and a few more runs, and those show up where a section needs them.

## Markdown reader run

First up is the `markdown` reader:

```sh
pandoc -f markdown -t html img-table.md
```

```html
<table>
<thead>
<tr>
<th>Item</th>
<th>Photo</th>
</tr>
</thead>
<tbody>
<tr>
<td>Desk</td>
<td><img src="desk.png" alt="Doe desk" /></td>
</tr>
<tr>
<td>Chair</td>
<td><img src="chair.png" style="width:50.0%" alt="Doe chair" /></td>
</tr>
</tbody>
</table>
```

Each image landed in its own `<td>`, and the bracket text turned into an `alt` attribute. The text cells beside them came out as plain `<td>Desk</td>` and `<td>Chair</td>`. With `markdown` as the reader, the Chair image also gained `style="width:50.0%"`.

Each reader has its own extension list in pandoc. For `markdown`, line 51 reads `+pipe_tables`, meaning `markdown` begins with that extension enabled.

## Plain commonmark run

Swap the reader and run the same file:

```sh
pandoc -f commonmark -t html img-table.md
```

```html
<p>| Item | Photo | |---|---| | Desk | <img src="desk.png"
alt="Doe desk" /> | | Chair | <img src="chair.png"
alt="Doe chair" />{width=50%} |</p>
```

Under plain `commonmark`, pandoc wrote a single `<p>`. In that plain `commonmark` paragraph, the pipes and the delimiter row stayed as ordinary characters, and no `<table>`, `<th>` or `<td>` appeared. Plain `commonmark` still turned both images into `<img>` elements inside the paragraph. In the plain `commonmark` run, `{width=50%}` stayed as literal text after the Chair image.

For plain `commonmark`, line 16 of its list is `-pipe_tables`, and that fits the missing table: the extension begins disabled there.

The pipe file gave one paragraph under plain `commonmark` too, and its two images carried `alt="Doe | desk"` and `alt="Doe | lamp"`. Plain `commonmark` built no table here, so the bare pipe had no cell to split.

## Run under commonmark+pipe_tables

Appending `+pipe_tables` to the reader name gave a table back:

```sh
pandoc -f commonmark+pipe_tables -t html img-table.md
```

```html
<table>
<thead>
<tr>
<th>Item</th>
<th>Photo</th>
</tr>
</thead>
<tbody>
<tr>
<td>Desk</td>
<td><img src="desk.png" alt="Doe desk" /></td>
</tr>
<tr>
<td>Chair</td>
<td><img src="chair.png" alt="Doe chair" />{width=50%}</td>
</tr>
</tbody>
</table>
```

The header and the Desk row match the `markdown` run line for line. The Chair row is where `markdown` and `commonmark+pipe_tables` part ways, and the next section takes that row apart.

One extra file tests a cell that mixes an image with words. Its file, `imgtab-mixed-cell.md`, has one data row:

```text
| Desk | ![Doe desk](desk.png) for Jane Doe |
```

With `commonmark+pipe_tables`, that cell came out as `<td><img src="desk.png" alt="Doe desk" /> for Jane Doe</td>`. The `markdown` reader wrote that exact line as well. An image plus trailing words fit in one cell here, both with `markdown` and with `commonmark+pipe_tables`.

## A width attribute after the image

Here `markdown` and `commonmark+pipe_tables` handled `{width=50%}` in different ways. Under `markdown` it was converted to a `style="width:50.0%"` attribute. With `commonmark+pipe_tables`, those braces stayed in the cell as text following the `<img>` tag.

The extension lists line up with that split. At line 37, `+link_attributes` appears in the `markdown` list, which means `markdown` begins with it enabled. The `commonmark` list runs to 30 lines, and none of them names `link_attributes`. What the `commonmark` list does hold, at line 3, is `-attributes`.

The extra script added that one to the run as `commonmark+pipe_tables+attributes`. Pandoc accepted the name with rc 0, and the Chair cell came out as:

```html
<td><img src="chair.png" style="width:50.0%" alt="Doe chair" /></td>
```

That line matches the Chair cell from the `markdown` run.

A width with no unit took a different form. The extra file `imgtab-width40.md` carries `{width=40}` in place of the percent value, and under `markdown` pandoc wrote:

```html
<td><img src="chair.png" width="40" alt="Doe chair" /></td>
```

For `markdown`, a percent ended up in `style`, while a plain number became its own `width` attribute. What size values mean outside a table belongs to the image size post linked in the intro.

## A pipe character inside alt text

The pipe file under `markdown` gave this:

```sh
pandoc -f markdown -t html img-table-pipe-alt.md
```

```html
<table>
<thead>
<tr>
<th>Item</th>
<th>Photo</th>
</tr>
</thead>
<tbody>
<tr>
<td>Desk</td>
<td>![Doe</td>
</tr>
<tr>
<td>Lamp</td>
<td><img src="lamp.png" alt="Doe | lamp" /></td>
</tr>
</tbody>
</table>
```

On the Desk row, the photo cell held `![Doe` and nothing more. The bare `|` in the alt text split the cell at that spot, so no `<img>` formed, and the text after that pipe did not reach the output. The Lamp row kept its image, and the `\|` from the source came out as `alt="Doe | lamp"`.

Next, that pipe file was fed to the other table reader:

```sh
pandoc -f commonmark+pipe_tables -t html img-table-pipe-alt.md
```

That run printed the same eighteen lines. Both table readers cut the Desk cell to `![Doe`, and both kept the Lamp alt text whole.

In the runs here, a backslash before the pipe kept the alt text in one piece under both table readers. Other characters that take a backslash are listed in [Markdown escape characters](markdown-escape-characters.md).

## Counting tables with grep

Each command below ran in the test folder as part of the extra script. To repeat them on another file, swap its name for `img-table.md`.

```sh
cat img-table.md
pandoc -f markdown -t html img-table.md -o imgtab-out-markdown.html
pandoc -f commonmark -t html img-table.md -o imgtab-out-commonmark.html
pandoc -f commonmark+pipe_tables -t html img-table.md -o imgtab-out-pipe.html
grep -c '<table>' imgtab-out-markdown.html
grep -c '<table>' imgtab-out-commonmark.html
grep -c '<table>' imgtab-out-pipe.html
grep -c 'style=' imgtab-out-markdown.html
grep -c 'style=' imgtab-out-pipe.html
grep -c '{width=50%}' imgtab-out-pipe.html
```

1. Read what `cat` printed and spot the rows holding an image.
2. Write one HTML file per reader setting with the three `pandoc` lines. Each of them ended with rc 0 in the extra log.
3. Count `<table>` lines in those files. The `markdown` file gave `1`, the plain `commonmark` file gave `0`, and `imgtab-out-pipe.html` gave `1`.
4. Count `style=` in the `markdown` file and then in the pipe file. That gave `1` for the `markdown` file and `0` for the `commonmark+pipe_tables` file.
5. Search the pipe file for the leftover braces. For `commonmark+pipe_tables`, that search found `1`.

A `0` in step 3 means the plain `commonmark` run produced no table for the file. A `1` in step 5 means the size block reached the `commonmark+pipe_tables` output as text.

Headings that hold links raise a similar reader question; a sibling post reports runs on [headings that carry a link](markdown-link-in-heading.md).

## Where Sashmark fits

If Sashmark's plan holds, you would fix a typo on the very line you are reading. Its Round-Trip target is plain: after a save, the file on disk would differ only where you typed. Changes View is planned too, to point out lines an agent rewrote while you were away, in a folder with no git history as well.

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/).
