# MD059 - Table Column Alignment

## Summary

Enforces consistent column alignment in Markdown tables for improved readability in source form.

## Rationale

Well-aligned tables are significantly easier to read and edit in plain text. When table columns are properly aligned with appropriate padding, it improves the developer experience and makes code
reviews more pleasant. This rule helps maintain consistent table formatting throughout your documentation.

## Configuration

This rule is **disabled by default** to allow for conservative adoption. Enable it explicitly in your configuration:

```yaml
MD059:
  enabled: true  # Default: false (opt-in)
  style: aligned  # Options: aligned, compact, none
  max_width: 120  # Optional: auto-compact for wide tables
```

### Configuration Options

#### enabled

- **Type**: boolean
- **Default**: `false`
- **Description**: Whether to enable table column alignment checks

#### style

- **Type**: string
- **Default**: `aligned`
- **Options**:
  - `aligned` - Columns are padded with spaces for visual alignment
  - `compact` - Minimal spacing, no padding
  - `none` - Disable formatting (same as `enabled: false`)

#### max_width

- **Type**: number (optional)
- **Default**: `120`
- **Description**: Maximum table width in characters. Tables exceeding this width will automatically use compact formatting to prevent excessive line lengths. Set to `null` to disable this behavior.

## Examples

### Good ✅ (Aligned)

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

### Bad ❌ (Unaligned)

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

### Good ✅ (Compact)

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

## Unicode Support

This rule properly handles international characters:

### CJK Characters (Chinese, Japanese, Korean)

```markdown
| Name | City |
|------|------|
| Alice | 東京 |
| Bob   | 上海 |
```

CJK characters are correctly measured as double-width, ensuring proper alignment.

### Basic Emoji

```markdown
| Status | Task        |
|--------|-------------|
| ✅     | Complete    |
| ❌     | Failed      |
| 🎉     | Celebrating |
```

Most emoji are handled correctly for alignment purposes.

## Known Limitations

### Complex Emoji Sequences

**Important**: Tables containing Zero-Width Joiner (ZWJ) emoji sequences are automatically skipped and preserved as-is.

```markdown
| Family      | Description     |
|-------------|-----------------|
| 👨‍👩‍👧‍👦 | Family          |
| 👩‍💻      | Woman Developer |
```

This limitation exists because ZWJ emoji (emoji combined with U+200D Zero-Width Joiner) have inconsistent display widths across different terminals, fonts, and rendering engines. There is no reliable
way to calculate their visual width, making accurate alignment impossible.

**This is an honest limitation of terminal display technology** , similar to what other tools like markdownlint and prettier experience. Rather than risk corrupting your tables with incorrect
alignment, this rule preserves them exactly as written.

### Why Not Fix This?

The Unicode width of complex emoji depends on:

- Terminal implementation (iTerm2, Windows Terminal, VS Code terminal, etc.)
- Font rendering (different fonts render emoji at different widths)
- Operating system (macOS, Linux, Windows handle emoji differently)
- Color emoji vs text emoji presentation

Since there's no universal solution, the honest approach is to skip these tables rather than provide incorrect formatting.

## Fix Behavior

When automatic fixes are applied:

1. **Width Calculation**: Uses Unicode width measurements to calculate proper column widths
2. **Padding**: Adds trailing spaces to align columns
3. **Content Preservation**: Cell content is never modified, only spacing
4. **Alignment Indicators**: Preserves `:---`, `:---:`, and `---:` in delimiter rows
5. **Inline Code**: Pipes inside backticks are properly masked and not treated as column separators
6. **Max Width Fallback**: Tables exceeding `max_width` automatically switch to compact mode
7. **ZWJ Detection**: Tables with Zero-Width Joiner emoji are skipped entirely

## Edge Cases

### Inline Code with Pipes

Pipes inside inline code blocks are correctly handled:

```markdown
| Pattern           | Description |
|-------------------|-------------|
| `a\|b`            | Or operator |
| `[0-9]\|[a-z]`    | Regex       |
```

### Empty Cells

Empty cells are properly aligned:

```markdown
| Column A | Column B | Column C |
|----------|----------|----------|
| Data     |          | More     |
|          | Data     |          |
```

### Single Column Tables

Single-column tables are supported:

```markdown
| Items |
|-------|
| One   |
| Two   |
```

## Performance

This rule includes several optimizations:

- **Pre-computed Tables**: Uses cached table detection from `LintContext`
- **Efficient Width Calculation**: Leverages the `unicode-width` crate for fast measurements
- **Surgical Fixes**: Only modifies table rows that need alignment
- **Early Skip**: Tables with ZWJ emoji are detected early and skipped

## When to Use

Enable this rule when:

- You value readable source code
- Your team reviews markdown changes in pull requests
- You edit tables frequently and want consistent formatting
- You work with international content (CJK characters)

Consider keeping it disabled if:

- You prefer compact table syntax
- Your tables contain many complex emoji sequences
- You use automated table generation tools that produce unaligned tables

## Related Rules

- **MD055**: Table pipe style (controls leading/trailing pipes)
- **MD056**: Table column count (ensures consistent column counts)
- **MD058**: Blanks around tables (ensures proper spacing)

## References

- [GitHub Flavored Markdown Spec - Tables](https://github.github.com/gfm/#tables-extension-)
- [Unicode Width Specification](https://www.unicode.org/reports/tr11/)
- [Markdownlint MD056](https://github.com/DavidAnson/markdownlint/blob/main/doc/md056.md)

## Philosophy

This rule embodies "Honest Excellence": do what works perfectly for the majority of cases, document the limitations clearly, and never corrupt user data. By automatically skipping problematic tables
(ZWJ emoji), it maintains reliability while providing value for standard use cases.
