Metadata-Version: 2.4
Name: hascii
Version: 0.1.0
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Rust
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Topic :: Scientific/Engineering :: Visualization
License-File: LICENSE
Summary: Convert Graphviz DOT files to ASCII box-drawing art
Keywords: graphviz,ascii,dot,diagram,unicode
License: Apache-2.0
Requires-Python: >=3.9
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Repository, https://github.com/atemate/hascii

# hascii

Convert Graphviz DOT files to ASCII box-drawing art.

hascii reads a DOT graph, uses Graphviz for layout, and renders the result
using Unicode box-drawing characters -- suitable for embedding in source code,
docstrings, and plain-text documentation.

## Example

```
                  ┌─────────────────────────┐
                  │ start_while_simple_flow │
                  └─────────────────────────┘
                               │
                               │
                               ▼
                       ┏┅┅┅┅┅┅┅┅┅┅┅┅┅┅┓
                       ┇ handler_init ┇
                       ┗┅┅┅┅┅┅┅┅┅┅┅┅┅┅┛
                               │
                               │
                               ▼
           ┌┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┐
           ┆ router_while_simple_flow_seq_set_i_2 ┆
           ┆                                      ┆
           ┆              p['i'] = 0              ┆
           └┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┘
                               │
                               │
                               ▼
    ┌┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┐
 ┌─▶┆ router_while_simple_flow_while_i_lt_max_iterations ┆
 │  └┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┘
 │                             │p['i'] < p['max_iterations']
 │                             └─────────────────────────────────┐
 │                             │                                 │else
 │                             ▼                                 │
 │          ┌┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┐               ▼
 │          ┆ router_while_simple_flow_seq_set_i ┆     ┌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┐
 │          ┆                                    ┆     ╎ handler_finalize ╎
 │          ┆            p['i'] += 1             ┆     └╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌┘
 │          └┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┘               │
 │           ┌─────────────────┘                                 │
 │           ▼                                                   │
 │  ┏┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┓                                          ▼
 └──┇ handler_process ┇                                          ●
    ┗┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┅┛
```

<details>
<summary>Source DOT and rendered PNG</summary>

DOT source: [flow.dot](img/sample-asya-flows/03_while_loop/flow.dot)

Graphviz rendering:

![flow.png](img/sample-asya-flows/03_while_loop/flow.png)
</details>

Node fill colors are represented as border styles (`--no-color` mode):

| Border | Color family | Example colors |
|--------|-------------|----------------|
| `┌──┐ │` solid | Green | palegreen |
| `┌┄┄┐ ┆` light triple-dash | Orange/Yellow | wheat, gold |
| `┌╌╌┐ ╎` light double-dash | Red | lightsalmon, coral |
| `┏┅┅┓ ┇` heavy triple-dash | Blue | lightblue, cyan |
| `┏╍╍┓ ╏` heavy double-dash | Purple/Pink | plum, pink |
| `┏━━┓ ┃` heavy solid | Dark | black, darkgray |
| `‥‥‥ ‥` two-dot leader | Light achromatic | white, lightgray |

When output goes to a terminal, borders are colored with ANSI codes instead.
Use `--no-color` for plain text suitable for docstrings and files.

## Features

- Configurable maximum output width (`--width`)
- Multiple label trimming strategies (`--trim`): end, start, middle, smart
- Edge labels placed adjacent to their edges, never truncated
- Back-edge routing with direction-aware LEFT/RIGHT detection
- Fan-in/fan-out bus routing for clean merge/split lines
- Hue-based border styles (B/W) + ANSI foreground colors (TTY)
- Usable as both a CLI tool and a Rust library

## Installation

From source (requires Rust toolchain and Graphviz):

```sh
cargo install --path .
```

Or build without installing:

```sh
cargo build --release
```

Graphviz must be installed and the `dot` command available in PATH:

```sh
# Debian / Ubuntu
sudo apt-get install graphviz

# macOS
brew install graphviz
```

## Usage

```
hascii [OPTIONS] [FILE]

Options:
      --stdin                  Read DOT source from stdin
      --width <WIDTH>          Maximum output width in characters
      --trim <TRIM>            Label trimming strategy [default: smart]
      --max-label <MAX_LABEL>  Maximum label width in characters
      --no-color               Disable ANSI colors (use border styles instead)
  -v, --verbose...             Increase verbosity (-v, -vv, -vvv)
  -h, --help                   Print help
```

Examples:

```sh
# Render a DOT file
hascii flow.dot

# Pipe from stdin
echo 'digraph { A -> B -> C }' | hascii --stdin

# Constrain width for docstrings
hascii --width 72 --no-color flow.dot > flow.txt

# Trim long labels
hascii --max-label 30 flow.dot
```

## Trimming strategies

When labels exceed the available space, hascii trims them using `--trim`:

| Strategy | Example (budget 25) | Description |
|----------|---------------------|-------------|
| `end` | `router_text_impro...` | Keep prefix, append ellipsis |
| `start` | `...score_ge_threshold` | Prepend ellipsis, keep suffix |
| `middle` | `router_te...threshold` | Keep prefix and suffix, ellipsis in middle |
| `smart` | `router_text...threshold` | Split on `_`, keep informative word boundaries |

`smart` (the default) splits on underscores and greedily keeps whole segments
from both ends.

## Python usage

```sh
pip install hascii
```

```python
import hascii

dot = 'digraph { A -> B -> C }'
print(hascii.render(dot))

# With options
print(hascii.render(dot, max_width=60, trim="smart", no_color=True))

# From file
print(hascii.render_file("flow.dot"))
```

Requires Graphviz (`dot`) installed on the system.

## Rust library usage

```rust
use hascii::{render, RenderOptions};

let dot = r#"digraph { A -> B -> C }"#;
let options = RenderOptions::default();
let ascii = render(dot, &options).expect("render failed");
println!("{ascii}");
```

## License

Apache-2.0

