ascfix 0.3.0

Automatic ASCII diagram repair tool for Markdown files
Documentation

ascfix

Tests & Lints Security Audit Crates.io

Automatic ASCII diagram repair tool for Markdown files.

Overview

ascfix fixes misaligned ASCII diagrams in Markdown, especially those generated by LLMs. It normalizes box widths, aligns arrows, enforces uniform padding, and ensures diagrams remain maintainable.

Ideal for:

  • AI-generated documentation with ASCII diagrams
  • Markdown files with workflow diagrams
  • CI/CD pipeline documentation
  • Architecture diagrams in code repositories

Features

  • Safe mode: Normalize Markdown tables (default)
  • Diagram mode: Repair ASCII boxes and arrows
  • Fence repair: Fix code fence boundary issues (mismatched lengths, unclosed fences)
  • Check mode: Validate files without modifying (exit codes for CI/CD)
  • Conservative: Only fixes well-understood structures
  • Idempotent: Running twice produces identical output
  • Fast: Linear processing time
  • Safe: No panics on untrusted input

Installation

From crates.io

cargo install ascfix

From source

git clone https://github.com/evoludigit/ascfix.git
cd ascfix
cargo install --path .

Usage

# Check a file (default: safe mode, output to stdout)
ascfix README.md

# Fix a file in place (default: safe mode)
ascfix README.md --in-place

# Repair code fence boundaries
ascfix README.md --in-place --fences

# Enable diagram mode for box/arrow repair
ascfix README.md --in-place --mode=diagram

# Repair everything (fences + diagrams) - shorthand for --fences --mode=diagram
ascfix README.md --in-place --all

# Validate without modifying (check mode)
ascfix README.md --check --mode=diagram
# Returns exit code 1 if changes would be made

# Process multiple files
ascfix docs/*.md --in-place --mode=diagram

Modes

Mode Description Use Case
safe Fix only Markdown tables Conservative, safe for any file
diagram Fix boxes and arrows For files with ASCII diagrams
check Validate without writing CI/CD validation

Flags

Flag Description Default
--in-place Modify files instead of printing to stdout Off
--check Validate files without modifying (returns exit code 1 if changes needed) Off
--fences Repair code fence boundaries Off
--all Shorthand for --fences --mode=diagram Off
--mode Processing mode (safe, diagram, check) safe
--max-size Maximum file size to process (e.g., "100MB", "1GB") Unlimited

Examples

Safe Mode: Markdown Table Alignment

Before (inconsistent column widths):

| Name | Age | City |
|------|-----|----------|
| Alice | 30 | New York |
| Bob | 25 | Boston |
| Charlie | 35 | Chicago |

After (normalized columns):

| Name    | Age | City      |
|---------|-----|-----------|
| Alice   | 30  | New York  |
| Bob     | 25  | Boston    |
| Charlie | 35  | Chicago   |

Command:

ascfix table.md --in-place

Code Fence Repair

Before (mismatched fence lengths):

```python
def hello():
    print("Hello, World!")

**After** (balanced fences):
```markdown
`````python
def hello():
    print("Hello, World!")

**Also handles:**
- Unclosed fences (adds closing fence)
- Inconsistent lengths (uses longest)
- Preserves language specifiers
- Skips type mismatches (conservative approach)

**Command:**
```bash
ascfix docs/*.md --in-place --fences

Diagram Mode: Box and Arrow Alignment

Before (misaligned, inconsistent):

┌──────┐
│ Step │
└──────┘
┌─────────┐
│ Process  │
└─────────┘

After (normalized):

┌────────┐
│ Step   │
└────────┘
┌────────┐
│ Process│
└────────┘

Command:

ascfix workflow.md --in-place --mode=diagram

Diagram Mode: Box Width Normalization

Before (text too close to border):

┌────────┐
│Process │
└────────┘

After (proper padding):

┌─────────┐
│ Process │
└─────────┘

Diagram Mode: Complex Workflow

Before (AI-generated, misaligned):

Source Code
┌──────────────────┐
│ Build & Test     │
└──────────────────┘
  ↓
┌────────┐
│ Deploy │
└────────┘

After (normalized, consistent):

Source Code
┌─────────────────┐
│ Build & Test    │
└─────────────────┘
┌──────────────────┐
│ Deploy           │
└──────────────────┘

Diagram Mode: Box Padding and Arrow Alignment

Before (LLM-generated, text cramped against borders, arrows misaligned):

┌───────┐    ┌────────┐
│Process│    │Database│
└───────┘    └────────┘
   ↓          ↓
┌──────────────────┐
│ResultProcessor   │
└──────────────────┘

After (proper padding added, arrows aligned to box centers):

┌─────────┐    ┌──────────┐
│ Process │    │ Database │
└─────────┘    └──────────┘
     │             │
┌────────────────────────┐
│ Result Processor       │
└────────────────────────┘

Changes made:

  • Expanded boxes to fit content with 1-space padding
  • Aligned arrows to box center columns
  • Normalized interior spacing

Command:

ascfix workflow.md --in-place --mode=diagram

Diagram Mode: Multi-Step Pipeline with Inconsistent Arrows

Before (arrows at inconsistent positions, no padding):

Source Code
  ↓
┌──────────┐
│Build     │
└──────────┘
┌─────────────┐
│Test Suite   │
└─────────────┘
  ↓
┌──────┐
│Deploy│
└──────┘

After (arrows normalized to consistent columns, boxes expanded with padding):

Source Code
┌──────────────┐
│ Build        │
└──────────────┘
┌───────────────────┐
│ Test Suite        │
└───────────────────┘
┌────────────┐
│ Deploy     │
└────────────┘

Changes made:

  • Aligned all vertical arrows to consistent column
  • Added interior padding to all boxes (text no longer touching borders)
  • Expanded boxes to fit content with proper spacing

Command:

ascfix pipeline.md --in-place --mode=diagram

Diagram Mode: Horizontal Workflow with Inconsistent Alignment

Before (arrows offset from box edges, inconsistent padding):

┌──────┐
│Input │
└──────┘
  ──→
     ┌─────────┐
     │Processing│
     └─────────┘
        ──→
          ┌──────┐
          │Output│
          └──────┘

After (arrows snapped to box edges, uniform padding):

┌────────┐
│ Input  │
└────────┘
     ┌───────────────┐
     │ Processing    │
     └───────────────┘
          ┌────────┐
          │ Output │
          └────────┘

Changes made:

  • Expanded boxes to fit content with padding
  • Snapped arrow endpoints to box edge columns
  • Made padding uniform (1 space) inside boxes

Command:

ascfix workflow.md --in-place --mode=diagram

Check Mode: CI/CD Validation

Validate without modifying (useful for pull requests):

# Exit 0 if file is already normalized
# Exit 1 if file needs fixing
ascfix docs/*.md --check --mode=diagram

Perfect for GitHub Actions:

- name: Check diagram alignment
  run: ascfix docs/*.md --check --mode=diagram
  # Fails the build if any diagrams need fixing

Advanced Features in Diagram Mode

Box Style Variants

ascfix supports multiple box drawing styles and automatically preserves them:

Single-line boxes (default):

┌─────┐
│ Box │
└─────┘

Double-line boxes:

╔═════╗
║ Box ║
╚═════╝

Rounded-corner boxes:

╭─────╮
│ Box │
╰─────╯

All styles are detected, preserved, and normalized consistently. Mixed styles in the same diagram are handled correctly.


Nested Box Hierarchies

ascfix detects and supports parent-child box relationships. Parent boxes automatically expand to properly contain their children with appropriate margins:

Before (parent too small):

┌──────────────┐
│ Parent       │
│ ┌────────┐   │
│ │ Child  │   │
│ └────────┘   │
└──────────────┘

After (parent expanded with margins):

┌────────────────────┐
│ Parent             │
│                    │
│  ┌──────────────┐  │
│  │ Child        │  │
│  └──────────────┘  │
│                    │
└────────────────────┘

Conservative behavior: Deeply nested structures (>2 levels) or ambiguous relationships are handled gracefully.


Side-by-Side Box Alignment

ascfix automatically balances the width of horizontally adjacent boxes for visual consistency:

Before (inconsistent widths):

┌───────┐  ┌─────┐  ┌────────────┐
│ Box 1 │  │ B2  │  │ Box Three  │
└───────┘  └─────┘  └────────────┘

After (uniform widths):

┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Box 1       │ │ B2          │ │ Box Three   │
└─────────────┘ └─────────────┘ └─────────────┘

Enhanced Arrow Support

ascfix recognizes and normalizes various arrow styles:

  • Standard arrows: → ↓ ↑ ←
  • Double arrows: ⇒ ⇓ ⇑ ⇐
  • Extended arrows: ⟶ ⟹

All arrows are aligned to box centers and maintained at consistent columns throughout the diagram.


Connection Lines (Conservative)

ascfix supports L-shaped connection paths with limited scope (4 segments maximum per connection):

┌────────┐
│ Start  │
└───┬────┘
    │
    └─────┬─────────┐
          │         │
      ┌───▼───┐ ┌──▼──┐
      │ Path1 │ │Path2│
      └───────┘ └─────┘

Connection detection is conservative to avoid false positives. Very complex paths are skipped.


Label Preservation (Framework)

ascfix includes framework support for preserving text labels attached to primitives during normalization. Label detection and rendering are currently conservative (skeleton implementation):

  • Labels attached to boxes are tracked
  • Labels attached to arrows are preserved
  • Relative offsets are maintained during normalization
  • Collision detection prevents label-diagram overlap

Building & Testing

# Run all tests
cargo test

# Check code quality
cargo clippy --all-targets --all-features -- -D warnings

# Build release binary
cargo build --release

All code is tested with TDD discipline - unit tests, integration tests, and golden file tests.

Documentation

License

Licensed under the MIT License (LICENSE or https://opensource.org/licenses/MIT)

Contribution

Contributions are welcome! Please feel free to submit pull requests.