# 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

```toml
[MD060]
enabled = false      # Default: opt-in for conservative adoption
style = "aligned"    # Options: "aligned", "compact", "tight", "any"
max-width = 0        # Default: inherit from MD013's line-length
```

### 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"`, `"compact"`, `"tight"`, `"any"`

Controls the table formatting style:

- **`aligned`**: Columns are padded with spaces for visual alignment (recommended for readability)
- **`compact`**: Minimal spacing with single spaces between pipes and content
- **`tight`**: No spacing, pipes directly adjacent to content
- **`any`**: 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): Inherits the threshold from MD013's `line-length` setting (typically 80)
- **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.

**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.

## Examples

### ❌ Incorrect (unaligned)

```markdown
| Name | Age | City |
|---|---|---|
| Alice | 30 | Seattle |
| Bob | 25 | Portland |
```

### ✅ Correct (aligned)

```markdown
| Name  | Age | City     |
| ----- | --- | -------- |
| Alice | 30  | Seattle  |
| Bob   | 25  | Portland |
```

### Compact Style

When `style = "compact"`:

```markdown
| Name | Age | City |
| --- | --- | --- |
| Alice | 30 | Seattle |
| Bob | 25 | Portland |
```

### Tight Style

When `style = "tight"`:

```markdown
|Name|Age|City|
|---|---|---|
|Alice|30|Seattle|
|Bob|25|Portland|
```

## Auto-Compact Threshold

### Example: Inheriting from MD013

```toml
[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

```toml
[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):

```markdown
| Name | City |
| ---- | ---- |
| 中文 | 東京 |
```

**Basic Emoji:**

```markdown
| Status | Name |
| ------ | ---- |
| ✅     | Pass |
| ❌     | Fail |
```

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):**

```markdown
| Emoji    | Name      |
| -------- | --------- |
| 👨‍👩‍👧‍👦 | Family    |
| 👩‍💻     | Developer |
```

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:

1. **Calculates proper display width** for each column using Unicode width measurements
2. **Pads cells** with trailing spaces to align columns
3. **Preserves cell content** exactly (only spacing is modified)
4. **Respects alignment indicators** in delimiter rows:
   - `:---` → Left-aligned
   - `:---:` → Center-aligned
   - `---:` → Right-aligned
5. **Auto-compacts** tables exceeding `max-width` to prevent line length violations
6. **Skips tables with ZWJ emoji** to prevent alignment corruption
7. **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:

```toml
[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:

```toml
[MD060]
enabled = true
style = "compact"
```

### Allow Any Style

To check without enforcing:

```toml
[MD060]
enabled = true
style = "any"  # No enforcement, preserves existing formatting
```

## Integration with Other Rules

**MD013 (Line Length):**

- MD060's `max-width = 0` inherits from MD013's `line-length`
- Tables are auto-compacted when they would violate line length limits
- Can override with explicit `max-width` value

**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:

1. **Large diffs:** Enabling on existing codebases can produce massive formatting changes
2. **Opt-in adoption:** Teams should consciously decide to adopt table formatting
3. **Performance:** Unicode width calculations add overhead
4. **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.

## See Also

- [MD056](md056.md) - Table Column Count (validates table structure)
- [MD013](md013.md) - Line Length (works with MD060's auto-compact)
- [MD055](md055.md) - Table Pipe Style (validates pipe placement)
