--- name: tikz description: "Diagnose and fix residual TikZ label, arrow, box, and Bézier-path collisions with geometric calculations. Use when a generated .tex figure has overlapping labels or crossed arrows. Not for generating a new figure; use $figure or the upstream deck workflow." allowed-tools: Bash(pdflatex*), Bash(latexmk*), Bash(grep*), Bash(ls*), Read, Edit, Glob argument-hint: '[path/to/file.tex]' --- # TikZ Collision Audit **Purpose**: Find and fix residual visual collisions in TikZ figures in a given `.tex` file. Labels on arrows, text inside boxes, arrows crossing arrows — this skill catches them using measurement, not intuition. **The fundamental rule**: an AI agent cannot reliably eyeball where TikZ elements land. All placement must be verified mathematically before declaring it safe. --- ## Critical context: this is a repair tool, not the primary defense `tikz` runs **after** TikZ has been generated. It audits existing code and fixes what it finds. But it cannot reliably fix diagrams that were never built with measurement in mind. **The upstream defense** is writing TikZ safely from the start: 1. Every `\node` declares explicit `minimum width` and `minimum height` 2. Every edge label carries a directional keyword (`above`, `below`, etc.) 3. A coordinate map comment block precedes every `tikzpicture` 4. Standard diagram types use canonical safe templates 5. `scale` is never used on complex diagrams When new decks are authored via `beamer-deck`, prefer applying these rules during generation. `tikz` is the downstream cleanup pass for anything that slipped through or for legacy/hand-written TikZ. **When upstream rules were applied**: `tikz` should find few or no issues. Run it as a check. **When upstream rules were NOT applied** (legacy TikZ, hand-written diagrams, inherited decks): `tikz` does its best, but expect more findings, more iteration, and lower reliability on autosized nodes and scaled diagrams. The companion reference `tikz_rules.md` (in this skill's directory) contains the full formulas and worked examples — read it once before running the audit passes below. --- ## Step 1: Identify the file and run the pre-check If the user specified a file, use it. If not, ask. Then: ```bash grep -n "tikzpicture\|begin{frame}\|node\|draw\|bend\|foreach" [file].tex | head -100 ``` Get a sense of scope: how many TikZ diagrams, how many frames, how many arrows. ### Pre-check: were the generation rules followed? Before running the six audit passes, quickly assess whether the TikZ was written safely: ```bash # Check for autosized nodes (no minimum width/height) grep -n "\\\\node" [file].tex | grep -v "minimum" ``` ```bash # Check for scale on tikzpicture grep -n "scale=" [file].tex ``` ```bash # Check for coordinate map comments grep -n "% Coordinate map\|% Node map\|% Layout" [file].tex ``` **If autosized nodes are widespread**: warn that repair reliability will be lower. The fix is upstream — add explicit dimensions to every node. Consider doing that first before running the audit passes. **If `scale` is used on a complex diagram**: warn that coordinates are compressed but text is not. Gap calculations in Passes 2–5 must compensate for the scale factor, but this compensation is fragile. The better fix is upstream: redesign at intended size. **If no coordinate map exists**: the audit will take longer because spatial relationships must be reverse-engineered from the code rather than read from a plan. --- ## Step 2: For each TikZ diagram, run all 6 Passes in order Full rules and formulas are in `tikz_rules.md` alongside this SKILL. Read it if you haven't. What follows is the operational checklist — the reference file has the formulas and worked examples. --- ### Pass 0: Cross-slide consistency ```bash grep -n "node.*{" [file].tex | grep -v "^[[:space:]]*%" ``` If the same diagram appears on multiple slides: colors, positions, and font sizes must be identical across all instances. Only the deliberate change (a new highlight, a new node) should differ. --- ### Pass 1: Bézier curves — do this FIRST ```bash grep -n "bend" [file].tex ``` For **each** curved arrow found, compute: ``` chord_length = distance between the two endpoints max_depth = (chord_length / 2) × tan(bend_angle / 2) safe_zone = max_depth + 0.5cm ``` Quick reference: | Bend | tan(angle/2) | |------|-------------| | 20° | 0.176 | | 25° | 0.222 | | 30° | 0.268 | | 35° | 0.315 | | 40° | 0.364 | | 45° | 0.414 | **Check 1**: Is any label within `safe_zone` of the baseline, in the direction the curve bends? If yes → move the label. **Check 2**: Does the curve cross any other arrow in the same figure? Curves bending down cross vertical arrows. Fix: reverse the bend direction. --- ### Pass 2: Label-between-nodes gap calculation For every arrow label placed between two nodes: ``` Available gap = center-to-center distance − half-width(A) − half-width(B) Usable space = Available gap − 0.6cm [0.3cm padding each side] ``` Estimate label width using character counts: | Font | Width/char | |--------------|-----------| | `\scriptsize` | 0.10 cm | | `\footnotesize`| 0.12 cm | | `\small` | 0.15 cm | | `\normalsize` | 0.18 cm | | Bold | +10% | **Known limitation**: these estimates break down for math mode (`$\beta$` is wider than 1 character), `\textbf` content, multi-word labels, and anything non-ASCII. When in doubt, overestimate width by 20%. **If `scale` is in effect**: multiply the usable space by the scale factor, but leave the label width estimate at native size. This is the core of the `scale` problem — coordinates shrink, text does not. If **estimated label width > usable space**: guaranteed collision. Fix: move above/below, or shorten text, or increase node spacing. **The most common fix** for labels that exceed the gap: break the label out as a standalone `\node` positioned above the arrow midpoint — clear of both boxes — rather than as an inline edge label. --- ### Pass 3: Arrow label positioning keywords ```bash grep -n "node\[" [file].tex | grep -v "above\|below\|left\|right\|anchor\|pos\|midway\|near" ``` Every arrow label must carry a directional keyword. Any `node[...]` on an arrow without `above`, `below`, `left`, `right`, `anchor=`, `pos=`, or `midway` will sit ON the arrow line. Fix: add the keyword. --- ### Pass 4: Labels vs. drawn shapes (Boundary Rule) For every `\node`, `\fill`, `\draw` circle/rectangle: compute the boundary. Any text within 0.4cm of a shape edge is a collision. **Circles**: center `(cx, cy)`, radius `r` → boundary from `cy − r` to `cy + r` **Rectangles/boxes**: bottom-left `(x,y)`, width `w`, height `h` → top edge at `y + h` If a label coordinate puts it inside or touching a shape boundary — move it 0.4cm outside. **Note on `scale`**: `scale=0.8` shrinks coordinates but NOT text. A 2 cm gap becomes 1.6 cm, but a `\small` label stays `\small`. Recalculate all gaps accounting for scale. **If the diagram uses `scale` on a complex figure, flag this to the user as an upstream problem — the reliable fix is to redesign at intended size, not to compensate in the audit.** --- ### Pass 5: Margin check Minimum clearances: | Pair | Minimum | |-------------------------------|---------| | Label ↔ label | 0.3 cm | | Label ↔ axis line | 0.3 cm | | Label ↔ arrow | 0.3 cm | | Arrow origin ↔ box edge | 0.15 cm | | Label ↔ shape boundary | 0.4 cm | | Any object ↔ slide edge | 0.5 cm | Also check: - Multi-line nodes have `align=center` or `align=left`? - No node text clipped by the slide margin? - If `scale` is used: did text get unintentionally large relative to shrunken coordinates? --- ### Pass 6: Debug bounding-box verification **Do NOT attempt to visually inspect the PDF by "eyeballing."** An AI agent cannot reliably see TikZ collisions in rendered PDFs. Instead, use a debug bounding-box approach: 1. **Temporarily add red debug outlines** around every node to make bounding boxes structurally visible: ```latex % DEBUG — add to preamble temporarily, remove before shipping \tikzset{every node/.append style={draw=red, very thin}} ``` 2. **Compile and inspect**: with red outlines, overlapping bounding boxes are visible as overlapping red rectangles. This makes collisions structurally obvious rather than visually estimated. 3. **For each red-box overlap found**: go back to the source, fix the coordinates or dimensions, remove the debug line, and recompile. 4. **Remove the debug line** before declaring the audit complete. The debug outlines are a diagnostic tool, not a permanent addition. This replaces the older instruction to "open the PDF and visually confirm." The debug-outline method catches the same problems but does not depend on Claude's unreliable ability to interpret rendered PDF geometry. --- ## Step 3: Fix, recompile, repeat After making fixes, prefer `latexmk` (the user's default): ```bash latexmk -pdf -interaction=nonstopmode [file].tex 2>&1 | grep -E "Overfull|Underfull|Error|Warning" ``` or `pdflatex` if `latexmk` isn't set up for the file: ```bash pdflatex -interaction=nonstopmode [file].tex 2>&1 | grep -E "Overfull|Underfull|Error|Warning" ``` Must return zero lines of Error. Fix any new Overfull/Underfull warnings introduced by the repositioning. Repeat until clean. --- ## Step 4: Re-audit the ENTIRE file after any fix One collision fix often reveals a second one nearby, or introduces a new label that now crowds a different object. After every change, re-run Passes 1–5 on **all** TikZ figures in the file — not just the one you just touched. ```bash grep -c "tikzpicture" [file].tex ``` That count is how many diagrams need a clean bill of health. --- ## Known limitations These are the cases where `tikz` is least reliable. When you encounter them, the better fix is almost always upstream (rewrite the TikZ safely) rather than downstream (try to repair it). | Limitation | Why it's hard | Upstream fix | |---|---|---| | **Autosized nodes** (no `minimum width`/`minimum height`) | Rendered dimensions depend on text content and font — `tikz` can only estimate, not compute exactly | Add explicit dimensions | | **`scale` on complex diagrams** | Coordinates shrink but text does not; gap calculations require fragile compensation | Redesign at intended size | | **Math-mode label widths** | `$\hat{\beta}_{it}$` is wider than character-count × width/char suggests | Overestimate by 20–30% or measure with a test compile | | **Nested `tikzpicture` environments** | Coordinate systems interact unpredictably | Flatten into a single environment | | **`\foreach` loops generating many nodes** | Gap calculations must be done per-iteration; easy to miss one | Write explicit nodes for small counts; check loop bounds for large counts | --- ## Common collision patterns and fast fixes | Pattern | Symptom | Fix | |---------|---------|-----| | Label between wide boxes | Text bleeds into box edge | Move label above arrow as standalone `\node` | | Step 1 / Step 2 labels on flow diagrams | Labels overlap box text | Place labels above the arrow band, not as edge labels | | Diagonal arrow label at `below right` | Label lands inside another box | Use `pos=0.55` + compute landing position | | Return curve crossing vertical arrow | Arrows intersect visually | Reverse bend direction (`bend left` ↔ `bend right`) | | Scale mismatch | Text large, gaps small | **Redesign at intended size; do not use `scale` on complex diagrams** | | Slope label on regression line | Label sits on the line | Use `node[anchor=west]` at a point 0.3cm off the line end | | `\\` inside `\textcolor{}` | Hbox overflow | Break into two separate `\textcolor` calls on separate lines | | Curve labels at right endpoints colliding with brace annotations | Labels horizontally adjacent at similar y | Move curve labels to different x position, or use a legend in the text column instead | --- ## Acknowledgments Ported from Scott Cunningham's MixtapeTools skill library (`resources/academics/scott-cunningham/MixtapeTools/.claude/skills/tikz/`). The companion `tikz_rules.md` is adapted from `MixtapeTools/.claude/skills/compiledeck/tikz_rules.md`. Upstream-defense references have been rewritten to point at `beamer-deck` and the user's unified `user-beamer` template.