MD060 - Table Format¶
Aliases: table-format
Enabled by default: No (opt-in)
Fixable: Yes
Rationale¶
Tables in Markdown are significantly easier to read and maintain when their columns are properly aligned in source form. While Markdown tables render the same regardless of spacing, aligned tables in source code:
- Improve readability during code review
- Make editing cells more intuitive
- Provide better developer experience
- Ensure consistency across documents
This rule enforces consistent column alignment and padding in Markdown tables, matching the behavior of popular formatters like Prettier.
Configuration¶
[MD060]
enabled = false # Default: opt-in for conservative adoption
style = "aligned" # Options: "aligned", "aligned-no-space", "compact", "tight", "any"
max-width = 0 # Default: inherit from MD013's line-length
column-align = "auto" # Options: "auto", "left", "center", "right"
Options¶
enabled¶
Type: boolean
Default: false
Whether to enable MD060 table formatting. This rule is disabled by default to allow gradual adoption, as it can make significant changes to existing tables.
style¶
Type: string
Default: "any"
Values: "aligned", "aligned-no-space", "compact", "tight", "any"
Controls the table formatting style:
aligned: Columns are padded with spaces for visual alignment (recommended for readability)aligned-no-space: Likealigned, but delimiter row has no spaces around dashes (see below)compact: Minimal spacing with single spaces between pipes and contenttight: No spacing, pipes directly adjacent to contentany: Preserve existing formatting style (no enforcement)
max-width¶
Type: number
Default: 0 (inherit from MD013)
Maximum table width before auto-switching to compact mode.
0(default): Smart inheritance from MD013's settings (see below)- Non-zero: Explicit max width threshold, independent of MD013
When a table's aligned width would exceed this limit, MD060 automatically uses compact formatting instead to prevent excessively long lines. This intelligent auto-compacting matches Prettier's table formatting behavior.
Smart Inheritance Behavior (when max-width = 0):
When max-width is not explicitly set, MD060 intelligently determines whether to apply width limits:
| MD013 Configuration | Effective max-width |
|---|---|
| MD013 disabled | Unlimited (no auto-compact) |
MD013.tables = false |
Unlimited (no auto-compact) |
MD013.line-length = 0 |
Unlimited (no auto-compact) |
MD013.tables = true and line-length = N |
Inherits N |
This means if you don't care about table line length (by disabling MD013 or setting tables = false), MD060 won't force tables to compact. Your aligned tables will stay aligned regardless of width.
Why this matters: Wide tables with many columns or long content can produce extremely long lines when aligned. Auto-compacting ensures tables don't violate line length limits while still maintaining alignment where practical. However, if you've explicitly opted out of line length checks for tables, MD060 respects that choice.
column-align¶
Type: string
Default: "auto"
Values: "auto", "left", "center", "right"
Controls how cell text is aligned within the padded column width:
auto(default): Respects alignment indicators from the delimiter row (:---for left,:---:for center,---:for right)left: Forces all columns to left-align text (content on left, padding on right)center: Forces all columns to center text (padding split on both sides)right: Forces all columns to right-align text (padding on left, content on right)
Note: This option only applies when style = "aligned" or style = "aligned-no-space". It has no effect on compact or tight styles (which have minimal or no padding).
Example:
Examples¶
❌ Incorrect (unaligned)¶
✅ Correct (aligned)¶
Compact Style¶
When style = "compact":
Tight Style¶
When style = "tight":
Column Alignment Examples¶
When column-align = "center":
When column-align = "right":
This is useful for consistently formatting tables with numeric data or when you want a specific visual style across all columns.
Aligned No-Space Style¶
When style = "aligned-no-space":
This style is identical to aligned except the delimiter row has no spaces around the dashes. Compare:
aligned:| ----- | --- | -------- |aligned-no-space:|-------|-----|----------|
Both styles produce aligned columns with equal-length rows. The only difference is the delimiter row formatting. This style is popular in hand-written tables and used by projects like GitLab and Obsidian.
Auto-Compact Threshold¶
Example: Inheriting from MD013¶
[MD013]
line-length = 100
[MD060]
enabled = true
style = "aligned"
max-width = 0 # Tables exceeding 100 chars will auto-compact
Behavior:
- Tables ≤ 100 chars wide: Aligned with full padding
- Tables > 100 chars wide: Automatically compact to stay under limit
Example: Explicit Threshold¶
[MD060]
enabled = true
style = "aligned"
max-width = 120 # Independent of MD013, uses 120 char threshold
Unicode Support¶
MD060 properly handles various Unicode characters:
✅ Supported¶
CJK Characters (Chinese, Japanese, Korean):
Basic Emoji:
The rule correctly measures CJK characters as double-width and aligns columns accordingly.
⚠️ Automatically Skipped¶
Tables containing complex Unicode sequences are automatically skipped to prevent alignment corruption:
- Zero-Width Joiner (ZWJ) emoji: 👨👩👧👦, 👩💻
- Zero-Width Space (ZWS): Invisible word break opportunities
- Zero-Width Non-Joiner (ZWNJ): Ligature prevention marks
- Word Joiner (WJ): Non-breaking invisible characters
These characters have inconsistent or zero display widths across terminals and fonts, making accurate alignment impossible. The rule preserves these tables as-is rather than risk corrupting them.
Example (automatically skipped):
This is an honest limitation of terminal display technology, similar to what other tools like markdownlint experience.
Fix Behavior¶
When applying automatic fixes (rumdl fmt), this rule:
- Calculates proper display width for each column using Unicode width measurements
- Pads cells with trailing spaces to align columns
- Preserves cell content exactly (only spacing is modified)
- Respects alignment indicators in delimiter rows:
:---→ Left-aligned:---:→ Center-aligned---:→ Right-aligned- Auto-compacts tables exceeding
max-widthto prevent line length violations - Skips tables with ZWJ emoji to prevent alignment corruption
- Masks inline code blocks to avoid treating code pipes as table delimiters
Common Use Cases¶
Recommended Configuration (Conservative)¶
For most projects, start with this conservative configuration:
[MD013]
line-length = 100
[MD060]
enabled = true # Enable table formatting
style = "aligned" # Align columns for readability
max-width = 0 # Auto-compact tables exceeding 100 chars
This provides readable tables without creating excessively long lines.
Strict Compact Mode¶
For projects preferring minimal formatting:
Allow Any Style¶
To check without enforcing:
Unlimited Table Width¶
For projects that want aligned tables without any width limits:
[global]
disable = ["MD013"] # No line length checks = no table compacting
[MD060]
enabled = true
style = "aligned"
max-width = 0 # Will be unlimited since MD013 is disabled
Or, if you want MD013 for code but not tables:
[MD013]
line-length = 80
tables = false # Skip table line length checks
[MD060]
enabled = true
style = "aligned"
max-width = 0 # Will be unlimited since MD013.tables = false
Integration with Other Rules¶
MD013 (Line Length):
- MD060's
max-width = 0uses smart inheritance from MD013 - If MD013 is disabled or
tables = false, tables have unlimited width (no auto-compact) - If MD013 is enabled with
tables = true, tables are auto-compacted atline-length - Can override with explicit
max-widthvalue to ignore MD013 entirely
MD056 (Table Column Count):
- MD056 validates column count consistency
- MD060 formats tables after MD056 validates structure
- Use both rules together for comprehensive table linting
Performance Notes¶
Table formatting is computationally intensive due to Unicode width calculations. MD060 is optimized with:
- Efficient Unicode width caching
- Early bailout for complex Unicode sequences
- Parallel processing in fix mode (when multiple tables exist)
For large documents with many tables, expect formatting to take a few hundred milliseconds.
Rationale for Default Disabled¶
MD060 is disabled by default because:
- Large diffs: Enabling on existing codebases can produce massive formatting changes
- Opt-in adoption: Teams should consciously decide to adopt table formatting
- Performance: Unicode width calculations add overhead
- Conservative approach: Matches rumdl's philosophy of opt-in for aggressive formatting
We recommend enabling MD060 for new projects or when doing a formatting cleanup pass.