Skip to content

Zero-dependency Python linter for detecting and fixing misaligned AI ASCII art boxes in documentation

License

Notifications You must be signed in to change notification settings

fxstein/ascii-guard

ascii-guard

Zero-dependency Python linter for detecting and fixing misaligned ASCII art boxes in documentation.

License Python CI codecov Code style: ruff Type checked: mypy PRs Welcome


🎯 Why ascii-guard?

AI-generated ASCII flowcharts and diagrams often have subtle formatting errors where box borders are misaligned by 1-2 characters. This breaks visual integrity and makes documentation harder to read.

ascii-guard automatically detects and fixes these alignment issues, ensuring your ASCII art looks perfect.

✨ Key Features

  • πŸš€ Minimal dependencies - Zero for Python 3.11+, one tiny dep for Python 3.10 (tomli)
  • πŸ’Ύ Tiny footprint - Lightweight and fast
  • πŸ”’ Minimal supply chain risk - Pure stdlib on 3.11+
  • ⚑ Quick startup - No import overhead
  • πŸ“¦ Simple installation - One command, automatic dependency handling
  • 🐍 Python API - Stable programmatic interface for integration into pipelines and scripts
  • πŸ›‘οΈ Type-safe - Full mypy strict mode
  • βœ… Well tested - Comprehensive test coverage

πŸ“¦ Installation

We recommend using uv for the fastest installation experience, but pip and pipx are fully supported alternatives. uv provides faster dependency resolution and better reproducibility, while pip and pipx work with any standard Python environment.

Recommended: Using uv (Fastest)

# Install ascii-guard
uv tool install ascii-guard

Note: If uv is not installed, you may install it with: curl -LsSf https://astral.sh/uv/install.sh | sh

Alternative: Using pip

pip install ascii-guard

Alternative: Using pipx (Isolated Environment)

pipx install ascii-guard

That's it! No other dependencies needed.


πŸš€ Quick Start

Check files for ASCII art issues

ascii-guard lint README.md
ascii-guard lint docs/**/*.md

Auto-fix alignment issues

ascii-guard fix README.md
ascii-guard fix --dry-run docs/guide.md  # Preview changes first

Example 1: Simple Box

Before (misaligned):

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Box Content         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   ← Missing one character!

After (fixed):

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Box Content         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  ← Perfect alignment βœ“

Example 2: Flowchart

Before (multiple alignment issues):

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚    Start     β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚
β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”
β”‚    Step     β”‚        ← Right border misaligned
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚
β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”
β”‚     End      β”‚β”‚      ← Duplicate right border
└──────────────        ← Broken bottom right corner

After (all boxes aligned):

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚    Start     β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚
β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”
β”‚    Step      β”‚
β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚
β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”
β”‚     End      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

ascii-guard automatically detects and fixes alignment issues across multiple boxes, nested structures, and complex flowcharts.


🎭 Ignore Markers

Need to show intentionally broken boxes in your docs? Use ignore markers:

**❌ Common Mistake (don't do this):**

<!-- ascii-guard-ignore-next -->
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Box Content         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   ← Misaligned on purpose for demonstration

**βœ… Correct Way:**

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Box Content         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  ← Perfect alignment

The ignore markers are invisible in rendered markdown but tell ascii-guard to skip validation. Perfect for:

  • Before/after comparisons
  • Tutorial examples showing common mistakes
  • Documentation with intentionally broken examples

See USAGE.md for complete syntax and examples.


🎨 Supported Box-Drawing Characters

ascii-guard supports Unicode box-drawing characters:

Type Characters Description
Horizontal ─ (U+2500) Horizontal line
Vertical β”‚ (U+2502) Vertical line
Corners β”Œ ┐ β”” β”˜ Standard corners
T-junctions β”œ ─ ┬ β”΄ Connection points
Cross β”Ό Four-way intersection
Heavy lines ━ ┃ ┏ β”“ β”— β”› Bold variants
Double lines ═ β•‘ β•” β•— β•š ╝ Double-line variants

πŸ“‹ Validation Rules

ascii-guard checks for:

  1. Vertical alignment - All β”‚ characters in a column align
  2. Horizontal alignment - All ─ characters connect properly
  3. Corner correctness - Corner characters match adjacent lines
  4. Width consistency - Top, middle, and bottom borders match
  5. Content fit - Content stays within box borders

🐍 Python API

ascii-guard provides a stable Python API for programmatic use. Perfect for integrating into documentation pipelines, CI/CD scripts, or custom tooling.

from ascii_guard import lint_file, fix_file, detect_boxes

# Lint a file for issues
result = lint_file("README.md")
if result.has_errors:
    print(f"Found {len(result.errors)} alignment errors")
    for error in result.errors:
        print(f"  Line {error.line + 1}: {error.message}")

# Auto-fix alignment issues
result = fix_file("README.md", dry_run=True)  # Preview first
print(f"Would fix {result.boxes_fixed} boxes")

# Detect boxes without validation
boxes = detect_boxes("docs/guide.md")
print(f"Found {len(boxes)} ASCII art boxes")

Available functions:

  • lint_file() - Lint a file for ASCII art alignment issues
  • fix_file() - Fix alignment issues in a file
  • detect_boxes() - Detect ASCII art boxes without validation
  • validate_box() - Validate a single Box object
  • fix_box() - Fix a single Box object

Data models: Box, ValidationError, LintResult, FixResult

πŸ“– Full API documentation: See API Reference for complete details, type signatures, and advanced examples.


🀝 Contributing

We welcome contributions! Here's how to get started:

Prerequisites:

  • Python 3.10+
  • uv - Fast Python package manager
# Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh

# Fork and clone the repository
git clone https://github.com/YOUR-USERNAME/ascii-guard.git
cd ascii-guard

# One-step setup (creates venv, installs deps, configures hooks)
./setup.sh

# Use uv run for commands
uv run pytest              # Run tests
uv run ruff check .        # Lint code
uv run mypy src/           # Type check

# Make your changes and submit a PR

For detailed development guide, see docs/DEVELOPMENT.md

For contribution guidelines, see CONTRIBUTING.md


πŸ“„ License

Apache License 2.0 - see LICENSE for details.

Copyright 2025 Oliver Ratzesberger


πŸ”— Links


πŸ™ Acknowledgments

Inspired by the need for better ASCII art formatting in AI-generated documentation.

Built with ❀️ using only Python's standard library.


Note: ascii-guard is stable and actively maintained. Contributions and feedback are welcome!

About

Zero-dependency Python linter for detecting and fixing misaligned AI ASCII art boxes in documentation

Topics

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •