---
title: "Markdown table column width: when pandoc writes col tags"
slug: markdown-table-column-width
excerpt: "Under Dash counts and the 25 to 75 split, compare the delimiter row of one pipe table with the col widths pandoc wrote for it."
quickAnswer: "Under Two tables, one long row, both inputs appear with a character count for each of their lines. Under A row past 72 characters, the HTML for the short table and the long one is quoted, and two files one character apart are compared. The section Dash counts and the 25 to 75 split sets the delimiter row against the col lines pandoc wrote. Under Raising the columns limit, one run at a larger setting is quoted and runs near the long row's length are listed. The long file goes through the second reader in Adding pipe_tables to commonmark. Commands to repeat the test are numbered under Steps to check widths in your own file."
keyTakeaways:
  - "Character counts for the lines of both inputs are printed in Two tables, one long row."
  - "Two files one character apart are compared under A row past 72 characters."
  - "Delimiter dashes and col percentages are set against each other in Dash counts and the 25 to 75 split."
  - "Output from several columns settings on the long file is reported in Raising the columns limit."
  - "Look at Adding pipe_tables to commonmark for the long file under the second reader."
publishedDate: 2026-10-21
dateModified: 2026-10-21
author: Bobby Huang
cluster: B
role: post
status: published
faq:
  - q: How does pandoc pick column widths for a pipe table?
    a: "The section Dash counts and the 25 to 75 split shows the delimiter row next to the widths pandoc wrote for it."
  - q: Why did one table get a colgroup and another did not?
    a: "Set the two runs quoted under A row past 72 characters against each other."
  - q: Can I keep pandoc from writing col widths?
    a: "Under Raising the columns limit, one run of the long file at a larger setting is quoted and the other settings tried are listed."
  - q: Does commonmark with pipe_tables write widths too?
    a: "The long file's HTML from that reader sits in Adding pipe_tables to commonmark."
related:
  - markdown-tables
  - markdown-table-multiline-cells
  - markdown-code-blocks
---

In the pandoc run tested here, markdown table column width showed up as a percentage on each `<col>` line of the long file's HTML. Neither test file asks for a width anywhere, yet pandoc wrote `<col>` lines with percentages for one test file in this post and left them out for another. Both files carry one table, and the sole gap between them is how long a single row runs.

Each output below came from one Mac, and its pandoc reported release 3.8.3. Those outputs are what this post reports; how a program might lay the HTML out stays outside its scope. Pipe rules are explained in [Markdown tables](markdown-tables.md), and this post assumes them.

## Two tables, one long row

Each input holds a pipe table of three lines: header, delimiter, then a single body row. Here is `cat width-short.md`:

```text
| Step | Note |
|------|------------------|
| 1    | Open the file |
```

And here is `cat width-long.md`:

```text
| Step | Note |
|------|------------------|
| 1    | Open the file, read every heading, then mark each section that still needs a review |
```

The delimiter row matches in both files: 6 dashes over the first column and 18 over the second. Running `awk '{print length}'` on a file prints the length of each line in characters. For `width-short.md` it printed `15`, `27` and `24`. For `width-long.md` it printed `15`, `27` and `94`. So the body row is what changes, from 24 characters to 94.

Pipe tables are a pandoc extension. The `markdown` extension list shows `+pipe_tables` on line 51, which means it is on for that reader by default. For `commonmark`, line 16 reads `-pipe_tables`, so that reader needs it added by name.

## A row past 72 characters

The first command sent the short file through the `markdown` reader:

```sh
pandoc -f markdown -t html width-short.md
```

```html
<table>
<thead>
<tr>
<th>Step</th>
<th>Note</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Open the file</td>
</tr>
</tbody>
</table>
```

There's no `<colgroup>` in that output and no width style anywhere. The cells came out as bare `<th>` and `<td>` elements.

The same command on the long file gave this:

```sh
pandoc -f markdown -t html width-long.md
```

```html
<table>
<colgroup>
<col style="width: 25%" />
<col style="width: 75%" />
</colgroup>
<thead>
<tr>
<th>Step</th>
<th>Note</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Open the file, read every heading, then mark each section that still
needs a review</td>
</tr>
</tbody>
</table>
```

Now a `<colgroup>` follows the opening `<table>` tag, with one `<col>` per column and a width style on each. Pandoc also wrapped the long cell text onto a second line of HTML, right after the word `still`.

To find where the change kicks in, the extra test made two more files with the same header and delimiter rows. In `width-72.md` the body row is 72 characters long. In `width-73.md` it is 73, one period longer. Here is the 73-character file:

```text
| Step | Note |
|------|------------------|
| 1    | Open the file, read every heading, then mark the parts to fix. |
```

The 72-character file matches it except for that final period. With no `--columns` flag, `pandoc -f markdown -t html width-72.md` wrote no `<colgroup>`. The same command on `width-73.md` wrote one, and these four lines of it match the long file's:

```html
<colgroup>
<col style="width: 25%" />
<col style="width: 75%" />
</colgroup>
```

In this test, then, `<colgroup>` turned up once a row passed 72 characters, and a row of exactly 72 did not bring it in.

Why 72? Pandoc takes a `--columns` option. A second conversion of the long file in the extra test used `--columns=72`, and its HTML was compared with the flagless run. The `cmp` command found no difference and returned 0. That fits 72 being the value pandoc used when the flag was left off in this test.

## Dash counts and the 25 to 75 split

The delimiter row gives the first column 6 dashes and the second 18, for 24 in all. Six of 24 is 25 percent, and 18 of 24 is 75 percent. Those are the two numbers in pandoc's output:

```html
<col style="width: 25%" />
<col style="width: 75%" />
```

The cell text did not shift those numbers here. The 73-character file carries different body text from the long file, and it got the same 25 and 75.

The short file has the very same dashes and got no widths at all. Put together, the runs say two things about this table. The length of the body row decided whether widths showed up, and the dash counts matched the values once they did. Other dash counts were left untried, so other splits are outside what this test shows.

## Raising the columns limit

A larger number passed to `--columns` changed the long file's output:

```sh
pandoc -f markdown -t html --columns=200 width-long.md
```

```html
<table>
<thead>
<tr>
<th>Step</th>
<th>Note</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Open the file, read every heading, then mark each section that still needs a review</td>
</tr>
</tbody>
</table>
```

The `<colgroup>` is gone. The long cell text now sits on one line of HTML as well.

The extra test then tried values close to the row's 94 characters. With `--columns=93`, pandoc wrote a `<colgroup>`. With `--columns=94` and with `--columns=95`, it wrote none. The 73-character file run with `--columns=73` also gave no `<colgroup>`. Across those runs, widths came in when a row ran longer than the `--columns` value and stayed out when the row fit inside it.

## Adding pipe_tables to commonmark

The last of the four main runs sent the long file through `commonmark` with the extension switched on:

```sh
pandoc -f commonmark+pipe_tables -t html width-long.md
```

```html
<table>
<thead>
<tr>
<th>Step</th>
<th>Note</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Open the file, read every heading, then mark each section that still
needs a review</td>
</tr>
</tbody>
</table>
```

This reader wrote no `<colgroup>`, even with the 94-character row and no `--columns` flag. The cell text still wrapped after `still`, as it did under `markdown`. So under this reader the HTML line break showed up while the widths did not.

Grid tables also came out with a `colgroup` in an earlier test, quoted in the post on [multiline cells in grid tables](markdown-table-multiline-cells.md). To make a single cell span two columns or two rows, see [merging cells in a Markdown table](markdown-table-merge-cells.md).

## Steps to check widths in your own file

Each step below was run by the extra test, on `width-long.md`, from inside the test folder. Replace that file name with yours.

1. Print the length of each line: `awk '{print length}' width-long.md`. Here the body row printed `94`.
2. Convert with the `markdown` reader and save the HTML: `pandoc -f markdown -t html width-long.md -o width-long.html`.
3. Count the `<col>` lines with `grep -c '<col ' width-long.html`. The result was `2`, one per column.
4. Convert again with a higher limit: `pandoc -f markdown -t html --columns=100 width-long.md -o width-long-100.html`.
5. Count again with `grep -c '<col ' width-long-100.html`. It printed `0`, and grep exited with code 1 since nothing matched.
6. For the second reader, run `pandoc -f commonmark+pipe_tables -t html width-long.md` and search what it prints for `<colgroup>`.

When step 1 finds a line longer than your `--columns` value and step 3 counts `<col>` lines you did not want, compare against the output of step 4. The fenced blocks above follow the syntax laid out in [fenced code blocks in Markdown](markdown-code-blocks.md).

## Where Sashmark fits

When Sashmark's first version is ready, the plan is that a word on the formatted page could be changed in place. Under the intended Round-Trip, every other line of the file would stay exactly as written. Changes View, slated for the same version, should show what an agent altered between two of your reads, git or not.

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