CHANGELOG.md

# Changelog

## v0.3.1

### Bug fixes

- **Stacked layout gap inflation** — when `max_width` triggered vertical stacking,
  gap expansions computed for the wide layout were incorrectly reused, adding
  excessive vertical space between every node pair
- **Mindmap multi-line labels** — labels containing `\n` were inserted raw into
  connector strings, breaking line alignment. Now joined with ` · ` for inline
  display
- Gap expansion limited to source/target layers only — intermediate gaps that
  just carry straight vertical lines no longer get inflated

## v0.3.0

### New features

- **Progressive compaction** — when `max_width` is set and the graph is too wide,
  Boxart tries progressively compact settings (smaller gap, then padding) before
  falling back to canvas clamping. Ported from termaid's auto-fit behavior.

- **Layout stacking** — when compaction isn't enough, sibling nodes in the same
  layer are stacked vertically (single column) instead of side-by-side, keeping
  all nodes fully rendered with intact borders.

- **Syntax highlighting in themed output** — code nodes with `:language` now
  render with Makeup syntax colors (keywords, functions, strings, operators)
  alongside the theme's structural colors.

### Improvements

- `max_width` now operates at the canvas cell level instead of string truncation —
  no more broken box-drawing characters or split ANSI escapes
- Labels are pre-wrapped by the layout engine and stored in `Layout.wrapped_labels` —
  the shapes renderer no longer re-wraps at a hardcoded width
- `max_label_width` option correctly flows through the entire pipeline
- Mindmap renderer handles tuple vertices without crashing (`inspect` instead of `to_string`)
- `Boxart.Graph.with_direction/2` helper for direction changes

### Bug fixes

- Shapes module no longer re-wraps labels at hardcoded 20-char width, respecting
  the `max_label_width` option
- `stamp_node_style` preserves Makeup ANSI styles instead of overwriting them
  with the node theme color
- `render_ansi_chunk` passes through raw ANSI escapes from syntax highlighting
- Dialyzer spec fixed: `render_graph_canvas` uses `BGraph.t()` not `Graph.t()`

## v0.2.0

### New features

- **`max_width` option** — clamp output to terminal width by truncating lines
- **`max_label_width` option** — configurable word wrapping threshold (default: 20)

## v0.1.0

Initial release.

- Directed graph rendering from `Graph.t()` (libgraph)
- 17 node shapes (rectangle, diamond, rounded, hexagon, stadium, circle, cylinder, etc.)
- Code nodes with line numbers and optional Makeup syntax highlighting
- Edge styles via keyword labels (`:solid`, `:dotted`, `:thick`, `:bidirectional`, `:arrow_type`)
- Edge labels
- Subgraphs
- All 4 directions (TD, LR, BT, RL)
- Unicode and ASCII charsets
- Rounded and sharp edge corners
- ANSI color themes (default, mono, neon, dracula, nord, amber, phosphor)
- `Boxart.Diagram` behaviour for specialized renderers
- Specialized renderers: state diagrams, sequence diagrams, git graphs, Gantt charts, mindmaps, pie charts
- Mindmap renderer accepts `Graph.t()`
- Sugiyama layout with barycenter crossing minimization
- A* edge routing with soft obstacles and endpoint spreading
- Direction-aware canvas with bitfield junction merging