Skip to content

MD096 - Table rows should be sorted by a named column

Aliases: table-sort

Enabled by default: No (opt-in)

Fixable: Yes, unless the table contains HTML comments.

Configuration

[MD096]
enabled = true
column = "Name"
order = "asc"

You can also enable the rule with extend-enable = ["MD096"] under [global].

Option Type Default Description
enabled boolean false Enable this opt-in rule. Alternatively, use extend-enable.
column string Unset Column heading to sort by. No tables are sorted until this is supplied.
order string "asc" Ascending ("asc") or descending ("desc"); "ASC" and "DESC" are also accepted.

The configured column name is plain text. Matching ignores case and surrounding whitespace: column = "Name" matches Name, NAME, and **Name** in a table header. An unset or whitespace-only column does nothing; there is no implicit first-column sort.

Examples

With column = "Name", this table is out of order:

| Name | Plan |
| --- | --- |
| [Zulu](https://example.com/z) | Free |
| [Alpha][alpha] | Paid |

[alpha]: https://example.com/a

The fix moves complete body rows and leaves the header and delimiter unchanged:

| Name | Plan |
| --- | --- |
| [Alpha][alpha] | Paid |
| [Zulu](https://example.com/z) | Free |

[alpha]: https://example.com/a

Sorting behavior

  • Keys use the cell's text: link labels, image alt text, and code contents contribute; emphasis markers, HTML tags, and link destinations do not.
  • Inline math uses its contents, following rumdl's parser extensions.
  • Defined full, collapsed, and shortcut reference links use their labels. Undefined reference syntax remains literal text. Obsidian wikilinks use the alias when present.
  • Keys are trimmed and converted to Unicode lowercase, then compared lexically. This is deterministic, locale-independent ordering, not language-specific collation or full Unicode case folding. Accented letters can sort after ASCII letters.
  • Numbers are compared as text: 10 precedes 2 in ascending order.
  • Empty cells sort first in ascending order and last in descending order.
  • Equal keys retain their original order in both directions.
  • Cell source, row spacing, and pipe style are preserved. LF and CRLF files retain their line-ending style; mixed endings follow the shared fixer's normalization policy. MD060 can format the sorted table separately.

Scope and exceptions

Sorting changes the order readers see. This is why the rule is opt-in and requires an explicitly named column. Every matching table is selected, including tables in different sections of the same file. A Name column in a sponsors table might be intentionally ordered by sponsorship tier; exempt that table if appropriate:

<!-- rumdl-disable MD096 -->
| Name | Tier |
| --- | --- |
| Zulu | Gold |
| Alpha | Silver |
<!-- rumdl-enable MD096 -->

A disable on any line from the header through the last body row suppresses the whole table's sorting diagnostic and fix. The table-sort alias also works in disable comments. HTML comments inside a table prevent automatic sorting, even when they configure another rule; a diagnostic is still available for manual review.

Only parser-confirmed pipe tables are checked. The rule skips tables when:

  • the configured heading is absent or matches more than one column;
  • any body row has a different cell count from the header;
  • the parser recognizes additional body rows without pipes beyond the scanned table;
  • there are fewer than two body rows;
  • body rows have different container prefixes, such as mixed explicit and lazy blockquote continuations, or do not occupy consecutive source lines.

Tables inside lists and blockquotes are supported when their body prefixes are consistent. Code examples, raw HTML blocks, and malformed delimiters are left alone. MD056 can repair cell counts and MD075 can repair orphaned rows before sorting. Cell boundaries follow the Markdown flavor: an unescaped pipe inside a code span is a separator in GFM, while MkDocs treats it as code content. Escape code-span pipes (\|) in GFM tables to avoid ambiguous or extra columns.