ascfix
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
- 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
From source
Usage
# Check a file (default: safe mode, output to stdout)
# Fix a file in place (default: safe mode)
# Enable diagram mode for box/arrow repair
# Validate without modifying (check mode)
# Returns exit code 1 if changes would be made
# Process multiple files
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 |
Examples
Safe Mode: Markdown Table Alignment
Before (inconsistent column widths):
After (normalized columns):
Command:
Diagram Mode: Box and Arrow Alignment
Before (misaligned, inconsistent):
┌──────┐
│ Step │
└──────┘
┌─────────┐
│ Process │
└─────────┘
After (normalized):
┌────────┐
│ Step │
└────────┘
┌────────┐
│ Process│
└────────┘
Command:
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:
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:
Diagram Mode: Horizontal Workflow with Inconsistent Alignment
Before (arrows offset from box edges, inconsistent padding):
┌──────┐
│Input │
└──────┘
──→
After (arrows snapped to box edges, uniform padding):
┌────────┐
│ Input │
└────────┘
Changes made:
- Expanded boxes to fit content with padding
- Snapped arrow endpoints to box edge columns
- Made padding uniform (1 space) inside boxes
Command:
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
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
# Check code quality
# Build release binary
All code is tested with TDD discipline - unit tests, integration tests, and golden file tests.
Documentation
- ARCHITECTURE.md - Design overview, module structure, and data flow
- SECURITY.md - Security policies, audit status, and best practices
- CONTRIBUTING.md - Development guidelines and contribution process
- CHANGELOG.md - Version history and release notes
License
Licensed under the MIT License (LICENSE or https://opensource.org/licenses/MIT)
Contribution
Contributions are welcome! Please feel free to submit pull requests.